4385: [POI2015]Wilcze doły

来源:互联网 发布:bf2怎么修改大炮数据 编辑:程序博客网 时间:2024/05/16 02:04

题目链接

题目大意:给定一个长度为n的序列,你有一次机会选中一段连续的长度不超过d的区间,将里面所有数字全部修改为0
请找到最长的一段连续区间,使得该区间内所有数字之和不超过p

题解:权值非负,显然取长度为d的区间
由于区间长度固定,预处理g[i]=sum(a[i]–a[i-d+1]),这样就把区间转成了易于维护的点

枚举右端点R,随着R的增大,最优的L单调不减,可以使用尺取法
现在需要维护g[]的最值,这个就是滑动窗口

我的收获:……

#include <iostream>#include <cstdio>using namespace std;const int M=2000005;int n,d,ans,q[M];long long p,f[M],g[M],s[M];void work(){    int l=1,r=0;    for(int L=1,R=d;R<=n;R++){        int now=R-d+1;        while(l<=r&&g[now]>g[q[r]]) r--;        q[++r]=now;        while(s[R]-s[L-1]-g[q[l]]>p){            L++;if(l<=r&&q[l]<L) l++;        }        ans=max(ans,R-L+1);    }    cout<<ans<<endl;}void init(){    cin>>n>>p>>d;    for(int i=1;i<=n;i++) scanf("%lld",&s[i]),s[i]+=s[i-1];    for(int i=1;i<=n;i++) g[i]=s[min(i+d-1,n)]-s[i-1];//g[i]=sum(a[i]--a[i+d-1])}int main(){    init();    work();    return 0;}
原创粉丝点击