EZOJ #88
2024-10-21 05:38:20
分析
自然想到二分
我们二分一个长度,之后考虑如何线性判断是否合法
我们可以维护一个单调队列表示从i开始的长度为d的区间和的最大值
每次用一段区间和减去它包含的长度为d的区间最大值即可
但是我们发现这个数据范围有那么一点点会t的征兆
于是我们考虑消除掉二分的log
于是我们继续用单调队列维护,用双指针扫一下就可以了
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
inline int ra(){
int x=,f=;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-;s=getchar();}
while(isdigit(s))x=(x<<)+(x<<)+(s-''),s=getchar();
return x*f;
}
inline long long ra2(){
long long x=,f=;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-;s=getchar();}
while(isdigit(s))x=(x<<)+(x<<)+(s-''),s=getchar();
return x*f;
}
long long pre[],del[],a[],q[],m;
int id[],fi,tl;
int n,d;
int main(){
int i,j=,k;
n=ra(),m=ra2(),d=ra();
for(i=;i<=n;i++)a[i]=ra2();
for(i=;i<=n;i++)pre[i]=pre[i-]+a[i];
for(i=;i<=n-d+;i++)del[i]=pre[i+d-]-pre[i-];
int Ans=;
fi=,tl=;
q[tl]=del[];
for(i=d;i<=n;i++){
while(tl>=fi&&q[tl]<=del[i-d+])tl--;
q[++tl]=del[i-d+];
id[tl]=i-d+;
for(j;j<=i;j++){
while(id[fi]<j)fi++;
long long x=q[fi];
if(pre[i]-pre[j-]-x<=m){
Ans=max(Ans,i-j+);
break;
}
}
}
printf("%d\n",Ans);
return ;
}
最新文章
- 如何解决";";No boot device available(无可用的引导设备)”错误
- C# 蓝牙编程
- Scrum会议6(Beta版本)
- Netbeans Platform 工程,免安装JDK
- cocos2dx中的定时器及其分类
- Oracle 11gR2 create init script
- java里遍历map的常见方式
- PHP--变量部分知识点
- hadoop编译
- mysqldump 用法总结
- Spring boot 应用打包部署
- SceneKit:简单的3D游戏场景搭建
- 无敌简单快速的文件服务器sgfs
- 调用EntityManagerFactory错误:The import javax.persistence cannot be resolved
- Java JDK动态代理解析
- 【Vue.js】vue引入组件报错:该组件未注册?
- Codeforces 844F Anti-Palindromize 最小费用流
- Windows服务器时间不同步问题
- 前端组件化Polymer入门教程(5)——生命周期
- for循环计算阶乘