【bzoj4385】[POI2015]Wilcze doły

单调队列扫描,记录当前区间长度为d的一段的和的最大值,和当前区间和。

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
 
typedef long long LL;
typedef double DB;
 
#define INF 0x7fffffff
#define N 2000010
#define eps 1e-8
 
LL n,p,d;
LL ans;
LL s,s1;
LL l,r,cnt;
 
LL v[N],t[N],q[N];
 
int main()
{
    scanf("%lld%lld%lld",&n,&p,&d);
    ans=d;
    for (int i=0;i<n;i++)
        scanf("%lld",&v[i]);
    for (int i=0;i<d;i++)
        s1+=v[i];
    s=q[r++]=s1;
    for (int i=d;i<n;i++)
    {
        s+=v[i];
        s1+=v[i]-v[i-d];
        while (l<r && q[r-1]<s1)
            --r;
        t[r]=i-d+1;
        q[r++]=s1;
        while (s-q[l]>p)
        {
            s-=v[cnt++];
            while (l<r && t[l]<cnt)
                ++l;
        }
        LL L=i-cnt+1;
        ans=max(ans,L);
    }
    printf("%lld",ans);
    return 0;
}

  

posted @ 2016-05-31 22:27  Yangjiyuan  阅读(133)  评论(0编辑  收藏  举报