[TK] Blocks 单调栈
题目描述
给出 \(N\) 个正整数 \(a[1..N]\) ,再给出一个正整数 \(k\) ,现在可以进行如下操作:每次选择一个大于 \(k\) 的正整数 \(a[i]\) ,将 \(a[i]\) 减去 \(1\) ,选择 \(a[i-1]\) 或 \(a[i+1]\) 中的一个加上 \(1\) 。经过若干次操作后,问最大能够选出多长的一个连续子序列,使得这个子序列的每个数都不小于 \(k\) .
初步分析
其实这个题与下述题目等效:
给出 \(N\) 个正整数 ( \(a[i]-k\) ) 组成的序列,序列前 \(i\) 项和记为 \(s[i]\) ,求满足 \(s[i]> s[j]\) 且 \(i> j\) 的 \(j-i\) 的最大值.
我们来思考一下为什么两个问题会相等.
容易想到,只有平均数大于等于 \(k\) 的子序列经过操作后能够使其每个数都不小于 \(k\),等效于在 \(a[i]-k\) 构成的序列中求最大的和为非负的区间. 而区间和又等于 \(s[j]-s[i-1]\) ,即 \(s[j]-s[i-1]> 0\),整理得 \(s[j]> s[i-1]\),此时区间长度 \(j-i+1\) 即为答案.
因此,我们现在的问题就转化为,如何求这样的区间最大值.
区间最值
首先放出引理:若 \(s[i_{1}] < s[j],\ s[i_{2}]< s[j],\ i_{1} < i_{2} \le j\),那么 \(i_{2}\) 一定不是最优解.
根据此引理,我们定义有可能为最优解的条件:符合条件,且其左方没有符合条件的数.
所以,如果我们从左边遍历,遇到第一个符合条件的数,那么符合该条件的数只有它可能是最优解,所以我们直接改到下一个条件遍历.
总结出如下遍历步骤:
- 设定初始条件为 \(s[j]=0\).
- 从左向右尝试放入前缀和.
- 当前前缀和满足 \(s[i] > s[j]\),放入,并将 \(s[i]\) 作为新的条件.
- 不满足,忽略.
前缀和有正有负,那么为什么初始条件是 \(s[j]=0\) 呢. 这是为了防止将正的前缀和放进去. 因为实际上正的前缀和可以直接作为答案区间,不需要进行这步流程,我们把它放进去反而会跑错.
注意到此步骤可以用栈实现:
s.push(0);
for(int i=1;i<=n;++i){
sum[i]=sum[i-1]+a[i]-k;
if(sum[s.top()]>sum[id]){
s.push(id);
}
}
我们通过上述步骤,将栈内的内容维护成了一个严格单调递减的序列的下标,这样的话,只要满足 \(i < j\),就有 \(s[i]<s[j]\).
接下来我们来考虑如何求最大区间.
由上述引理,我们倒序遍历全部前缀和 \(s[i]\) , 设栈顶前缀和为 \(s[top]\),那么我们可以遍历到满足 \(s[top]<s[i]\) 的最后一个数,此时区间长度即为 \(i-top\).
代码实现
stack<long long> s;
long long a[1000001],sum[1000001];
void push(int id){
if(sum[s.top()]>sum[id]){
s.push(id);
}
}
long long calc(int n){
long long ans=0;
for(int i=n;i>=1;--i){
while(!s.empty()&&sum[i]-sum[s.top()]>=0){
ans=max(ans,i-s.top());
s.pop();
}
}
return ans;
}
int main(){
int n,m,k;
cin>>n>>m;
for(int i=1;i<=n;++i){
cin>>a[i];
}
for(int i=1;i<=m;++i){
cin>>k;
s.push(0);
for(int i=1;i<=n;++i){
sum[i]=sum[i-1]+a[i]-k;
push(i);
}
s.push(n);
cout<<calc(n)<<" ";
while(!s.empty()){
s.pop();
}
}
}
[TK] Blocks 单调栈的更多相关文章
- bzoj 2086 [Poi2010]Blocks 单调栈
[Poi2010]Blocks Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 788 Solved: 356[Submit][Status][Dis ...
- bzoj2086: [Poi2010]Blocks DP,单调栈
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2086 思路 这就有点妙了 题目意思就是让你求平均数>=k的最长序列 先求出a[i] ...
- poj 3415 Common Substrings(后缀数组+单调栈)
http://poj.org/problem?id=3415 Common Substrings Time Limit: 5000MS Memory Limit: 65536K Total Sub ...
- POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数
题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS Memory Limit: 65536K ...
- [bzoj2086][Poi2010]Blocks_单调栈_双指针
Blocks bzoj-2086 Poi-2010 题目大意:题目链接. 注释:略. 想法:首先,不难发现,如果连续的一段数的平均值不小于输入的k的话,这段数是满足题意的. 所以,我们再次简化一下:将 ...
- POJ - 3415 Common Substrings(后缀数组求长度不小于 k 的公共子串的个数+单调栈优化)
Description A substring of a string T is defined as: T( i, k)= TiTi+1... Ti+k-1, 1≤ i≤ i+k-1≤| T|. G ...
- BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 8748 Solved: 3835[Submi ...
- BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]
4453: cys就是要拿英魂! Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 90 Solved: 46[Submit][Status][Discu ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
- poj 2559 Largest Rectangle in a Histogram - 单调栈
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19782 ...
随机推荐
- 18B20的CRC8校验分析
CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定. CRC校验可以简单地描述为:例如我们要 ...
- 使用MySQL实现分布式锁
分布式锁开发中经常使用,在项目多节点部署或者微服务项目中,JAVA提供的线程锁已经不能满足安全的需求,需要使用全局的分布式锁来保证安全:分布式锁的实现的方式有很多种,最常见的有zookeeper,Re ...
- Fiddler使用界面介绍-右侧面板
右侧面板是对左侧请求进行解析的面板,点击左侧的请求右侧面板就会出现分析数据 1.Statistics关于HTTP请求的性能 2.Inspectors请求内容,包含请求数据和响应数据 3. AutoRe ...
- 【Java】Map 映射接口 概述
Map 映射接口 概述 Map是一个双列数据,存储K-V类型的数据 JDK1.2 - HashMap 是目前Map的主要实现类 JDK1.2 线程不安全的,效率高,可存储null的key和value ...
- ubuntu18.04 安装wine64出现错误: X 64-bit development files not found.
ubuntu18.04 编译源码方式安装 wine6.11 , 报错: 缺少依赖,解决方法如下: sudo apt install xserver-xorg-dev 参考: https://bl ...
- WSL启动nvidia-docker镜像:报错libnvidia-ml.so.1- file exists- unknown
参考: https://blog.csdn.net/xujiamin0022016/article/details/124782913 https://zhuanlan.zhihu.com/p/361 ...
- 秒懂全文:盘点13个各具特色的AI智能阅读助手工具
在当今信息爆炸的时代,AI阅读工具正在革新我们的阅读方式,成为了提高效率.优化阅读体验的关键. 这类AI阅读辅助工具,只需要上传文件或者输入链接,便可以直接以聊天对话的形式进行一键总结和智能问答,满足 ...
- springcloud集成grpc(一)
码云地址:https://gitee.com/lpxs/lp-springcloud.git 有问题可以多沟通:136358344@qq.com. GRPC简介 是谷歌开源的一个高性能的.通用的RPC ...
- java游戏服务器2023年7月22日
name 卡牌军团 放置卡牌游戏 开发语言: java mysql 通信http 账号服务器 提供验证等功能 中心服务器 跨服功能 排行榜 公会
- hacs安装
安装 HACS 直接使用 Docker 的可视化管理面板 Portainer 或者通过命令行进入 Docker 容器,然后执行以下安装命令: docker exec -it <容器名称或容器ID ...