P3594 WIL
P3594 WIL
题意很简化了已经
刚拿到题的时候我其实想的就是在一段大区间(答案区间)中找到长度为d的区间最大的区间,然后答案就是大区间的区间和减去长度为d的区间和,这个大区间找的时候用双指针,r一直右移,如果区间和减去长度为d的区间和大于了p,那左指针就右移,就这样一直找;
但是有两个问题,就是我怎么找这个大区间中长为d的最大区间,可以先提前预处理前缀和,sum[r]-sum[r-d]就是你要维护的值,而单调队列离要存下标(因为后边要用),另一个问题是,如果大区间左指针右移之后,你本来维护的那个长为d的区间就出了大区间了,那怎么解决?(我当时就是因为单调队列存的不是下标,然后就不会搞了,因为我没法判断它是不是出了大区间)因为单调队列存的是下标,所以,每次左指针右移时,都要while判断你存的那个区间是不是小于左指针即可,如果小于,那单调队列就出队头;
每次新加一个数都统计最大区间长度即可
下面是代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e6+10;
int n,p,d;
int q[N],a[N],ans,l,sum[N],t,h;
signed main()
{
cin>>n>>p>>d;
for(int i=1;i<=n;i++)scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];
ans=d,q[t]=d,l=1;
for(int i=d+1;i<=n;i++)
{
while(h<=t&&sum[i]-sum[i-d]>sum[q[t]]-sum[q[t]-d])--t;
q[++t]=i;
while(h<=t&&sum[i]-sum[l-1]-sum[q[h]]+sum[q[h]-d]>p)
{
++l;
while(h<=t&&q[h]-d+1<l)++h;
}
ans = max(ans,i-l+1);
}
printf("%lld", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现