LGP11261 [COTS 2018] 直方图 学习笔记

news/2025/2/24 3:25:39/文章来源:https://www.cnblogs.com/OrinLoong/p/18718384

LGP11261 [COTS 2018] 直方图 学习笔记

Luogu Link

前言

参考了这篇题解。算是对其更详细的一个解释。

题意简述

给定一宽为 \(n\) 的直方图,第 \(i\) 格的高度为 \(h_i\)。也就是说,对于 \(\forall 1\le i\le n\),第 \(i\) 格矩形的四个顶点分别为 \((i-1,0),(i,0),(i-1,h_i),(i,h_i)\)

pEKIR3j.md.png

给定正整数 \(p\),求出满足以下条件的网格矩形的数量:

  • 有一条边在 \(x\) 轴上。
  • 完全位于直方图内部。
  • 面积至少为 \(p\)

做法解析

首先想一想当一个矩形面积至少为 \(p\) 时意味着什么——\(ab>p\)。换句话说,当我们确定了矩形的高 \(b\) 的时候,我们就随之确定了 \(a\ge \lceil \frac{p}{b} \rceil\)

我们发现,当矩形的 \(lx,rx\) 确定之后,限制 \(ry\) 范围的正是 \(\min_{i=lx}^{rx} h_i\)。此时套路来了:我们以 \(i\) 为键,\(h_i\) 为值建一棵小根笛卡尔树,并考虑横跨每个最小值的贡献。具体来说我们对这棵笛卡尔树做一遍 \(dfs\),每搜到一个结点 \((i,h_i)\),我们就统计所有 \(lc\le lx\le i,i\le rx\le rc\) 的合法矩形的数量,其中 \(lc,rc\) 分别为当前结点子树里横坐标的最小值和最大值。这么做的道理在于可以不重不漏地计数。

pEKIWgs.md.png

令当前结点 \(u\) 的左子树大小为 \(L\),右子树大小为 \(R\)(实际上,\(L=u-lc,R=rc-u\))。现在问题变成了计算所有结点的 \(\sum_{i=0}^L\sum_{j=0}^{R} \max(h_u-\lceil\frac{p}{i+j+1}\rceil+1,0)\),其中的 \(\lceil\frac{p}{i+j+1}\rceil\) 代表着 \(i,j\) 确定后合法矩形高度的最小值,\(h_u-\lceil\frac{p}{i+j+1}\rceil+1\) 则自然是 \(i,j\) 确定后合法高度的种类。

pEKIfvn.md.png

考虑枚举较小的那一侧子树的 \(i\)(这里是启发式合并思想,保证复杂度 \(O(N\log N)\))。不妨设 \(L<R\),问题变为如何快速计算 \(\sum_{i=0}^{L}\sum_{k=i+1}^{i+R+1}\max(h_u-\lceil\frac{p}{k}\rceil+1,0)\)
显然最小的满足 \(h_u-\lceil\frac{p}{k}\rceil\ge 0\)\(k\) 就是 \(\lceil\frac{p}{h_u}\rceil\)
所以上式等价于算 \(\sum_{i=0}^{L}\sum_{k=\max(i+1,\lceil\frac{p}{h_u}\rceil)}^{i+R+1} h_u-\lceil\frac{p}{k}\rceil+1\)
也即等价于 \(\sum_{i=0}^L (i+R+1-\max(i+1,\lceil\frac{p}{h_u}\rceil))\times h_u-\sum_{k=\max(i+1,\lceil\frac{p}{h_u}\rceil)}^{i+R+1} \lceil \frac{p}{i} \rceil\)
注意到我们减去的那玩意就是个 \(\lceil \frac{p}{i} \rceil\) 的前缀和,预处理之即可。这道题就做完了!

时间复杂度 \(O(N\log N)\)

代码实现

代码很简单!

#include <bits/stdc++.h>
using namespace std;
namespace obasic{typedef long long lolo;template <typename _T>void readi(_T &x){_T k=1;x=0;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')k=-1;for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-'0';x*=k;return;}template <typename _T>void writi(_T x){if(x<0)putchar('-'),x=-x;if(x>9)writi(x/10);putchar(x%10+'0');}template <typename _T>void maxxer(_T &x,_T y){x=max(x,y);}template <typename _T>_T pcedi(_T x,_T y){return (x-1)/y+1;}
};
using namespace obasic;
const int MaxN=1e5+5;
int N,H[MaxN],stk[MaxN],ktp;
int ls[MaxN],rs[MaxN];lolo P,pre[MaxN],ans;
lolo calc(lolo l,lolo r,lolo h){maxxer(l,pcedi(P,h));if(l>r)return 0;return 1ll*(h+1)*(r-l+1)-(pre[r]-pre[l-1]);
}
lolo solve(int u,int cl,int cr){lolo res=0;int lsiz=u-cl,rsiz=cr-u;if(lsiz>rsiz)swap(lsiz,rsiz);lsiz++;for(int i=1;i<=lsiz;i++)res+=calc(i,i+rsiz,H[u]);if(ls[u])res+=solve(ls[u],cl,u-1);if(rs[u])res+=solve(rs[u],u+1,cr);return res;
}
signed main(){readi(N),readi(P);for(int i=1;i<=N;i++)pre[i]=pre[i-1]+pcedi(P,(lolo)i);for(int i=1;i<=N;i++)readi(H[i]);for(int i=1;i<=N;i++){int k=ktp;while(k&&H[stk[k]]>H[i])k--;if(k)rs[stk[k]]=i;if(k<ktp)ls[i]=stk[k+1];stk[++k]=i,ktp=k;}ans=solve(stk[1],1,N);writi(ans);return 0;
}

反思总结

我们考虑有顺序地枚举限制矩形高度的 \(h_i\),于是把问题搬到了笛卡尔树上!大概是一种套路。
更深刻的东西暂时想不出来/ll

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/884756.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【FOFA】借助测绘探寻Ollma调用

免责声明: ⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权!Fingers:app="Ollama" && is_domain=false根据Ollma官方接口可知 GET /api/tags HTTP/1.1 …

LCT(link cut tree)入门

简述 我们有这样一个问题:修改点权,询问链上的点权和。这明显是个树链剖分模版。 但如果还有这些操作呢:断开一条边,连上一条边,保证一直是森林。这就是动态树的一种问题。 而 LCT 就是解决这些问题的优秀数据结构。 前言 建议是会 Splay,虽然 FHQ-Treap 也能写,但是多一…

P1441 砝码称重(dfs)

要注意sum+a[i]的位置,我放错了,不知道为什么会re #include<iostream> #include<cstring> #define int long long using namespace std; int n,m,ans,a[30],vis[2020]; int f[2020]; int maxs; void check(){int sum=0;vis[0]=1;for(int i=1;i<=n;i++){if(f[i…

【PHP免杀】使用分支对抗进行Webshell Bypass

# webshell免杀 # PHP # 稻妻雷元素方块阵免责声明: 由于传播、利用本公众号所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任,一旦造成后果请自行承担!前言 对于webshell免杀来说类绕过是最有效果且不易被检测出来的,…

springcloud-conifg升级后的擦坑《一》

configServer的配置文件: 之前老板的的路径为: - /springcloud-config/order/order-dev.yml [版本HxtonSR12] client1请求的: client2请求的: 根目录下的config配置文件 本文来自博客园,作者:余生请多指教ANT,转载请注明原文链接:https://www.cnblogs.com/wangbiaoh…

GDB调试(二)

GDB调试 运行中程序GDB调试 测试程序 //test2.c //功能:从0开始每秒打印 #include <stdio.h> #include <unistd.h> int aaa(); int bbb(int n); int main() {aaa(); }int aaa() {bbb(0); }int bbb(int n) {for(int i = n; i < n+10000; i++){printf("i:%d\…

qt cmake加入程序exe图标

可以看到qt自动编译出来的图标是默认的,如下图所示 我想要更改成自定义的图标,比如下方的样子 下边是操作步骤: 图标选择与转化成ico通过这个网站将正常图片转化成ico:https://www.bitbug.net/创建rc文件将ico复制到cmakelist的同级目录下,然后新建文本文件,里边输入如…

100道codeforces 2500

首先小小容斥一下,用1~r的减去1~l-1的。 1~r的,可以想到数位dp 设f[len][pre][mod]表示从低位数第len位,当前数字的值%2450为pre,当前用过的数字的lcm为mod的方案数 使用limit表示是否贴着上界 #include<bits/stdc++.h> using namespace std; typedef long long ll; …

第六轮easy~hard

题目1代码 #include<bits/stdc++.h> using namespace std;const int MAX = 2e+5; int ary[MAX],prefix[MAX]; int main() {int n; cin>>n;for(int i=1;i<=n;i++){cin>>ary[i];prefix[i] = prefix[i-1] + ary[i];}int minGap = 0x7fffffff, maxSum = 0x80…

代码随想录算法训练营day4 | 24.两两交换链表中的节点、19.删除链表的倒数第N个节点、160.相交链表、142.环形链表Ⅱ

24.两两交换链表中的节点点击查看代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next…

倾斜摄影OSGB瓦块大小重划分

在倾斜摄影数据生产过程中或者使用时,经常会遇到生产的瓦块过大或者过小的问题,如果重新生成一来费时费力,二来有些数据原片都不一定还有,因此很多用户提出能否开发一个osgb瓦块大小重新划分的功能。 现在它来了,2025年的第一个版本更新,我们把这个功能加上了,新…

DeepSeek本地安装部署以及对外提供服务

本地安装部署参考博客:https://blog.csdn.net/weixin_47061482/article/details/145577119,这里就不赘述了。 下面说一下对外提供deepseek服务。 场景:本地部署了deepseek之后,在公司如何使用服务,又或者说把本地服务提供给其他人使用。 工具:chatbox:一款 AI 客户端应用…