zoukankan      html  css  js  c++  java
  • bzoj4385 Wilcze doły

    Description

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

    Input

    第一行包含三个整数n,p,d(1<=d<=n<=2000000,0<=p<=10^16)。
    第二行包含n个正整数,依次表示序列中每个数w[i](1<=w[i]<=10^9)。

    Output

    包含一行一个正整数,即修改后能找到的最长的符合条件的区间的长度。

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

    #include<cstdio>
    int n,d,v[2000002],t[2000002];
    long long p,s=0,s1=0,q[2000002];
    int ql=0,qr=0,lp=0,ans;
    inline int read(){
        int x=0,c=getchar();
        while(c>'9'||c<'0')c=getchar();
        while(c>='0'&&c<='9')x=x*10+c-48,c=getchar();
        return x;
    }
    int main(){
        scanf("%d%lld%d",&n,&p,&d);
        ans=d;
        for(int i=0;i<n;i++)v[i]=read();
        for(int i=0;i<d;i++)s1+=v[i];
        s=q[qr++]=s1;
        for(int i=d;i<n;i++){
            s+=v[i];
            s1+=v[i]-v[i-d];
            while(ql<qr&&q[qr-1]<s1)--qr;
            t[qr]=i-d+1;
            q[qr++]=s1;
            while(s-q[ql]>p){
                s-=v[lp++];
                while(ql<qr&&t[ql]<lp)++ql;
            }
            int l=i-lp+1;
            if(l>ans)ans=l;
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    leetCode-Two Sum
    leetCode-Pascal's Triangle II
    leetCode-Maximum Average Subarray I
    css 实现垂直水平居中
    poping 心法
    我的机密
    MSMQ消息队列的使用
    生成最大单号 scope_identity
    sqlserver ADO.net 查询数据库加锁,事务提交
    漂亮的JS插件
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5258062.html
Copyright © 2011-2022 走看看