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;
}
时间: 2024-10-14 00:36:35

bzoj4385 Wilcze do?y的相关文章

bzoj 4385: [POI2015]Wilcze do?y

4385: [POI2015]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 包含一行一个正整数,即修改后能

bzoj4385 &amp; POJ2015 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 包含一行一个正整数,即修改后能找到的最长的符合条件的区间的长度. Sample In

BZOJ4385 : [POI2015]Wilcze do?y

求出前缀和$s$,设$f[i]=s[i+d-1]-s[i-1]$. 从左到右枚举的右端点$i$,左端点$j$满足单调性,若$s[i]-s[j-1]-\max(区间内最大的f)\leq p$,则可行. 用单调队列维护即可,时间复杂度$O(n)$. #include<cstdio> #define N 2000010 int n,d,i,j,q[N],h,t,ans;long long p,sum,s[N],f[N]; inline void read(int&a){char c;whil

【BZOJ4385】[POI2015]Wilcze do?y【单调队列】【前缀和】【Two Pointers】

[题目链接] 题解: 如果区间[j, i]固定,那么一定是将权值最大的一段变为0. 用单调队列维护一段区间内权值最大的子段下标(这里记录右端点下标,设为x),枚举右端点i,用尺取法计算出j. 一段区间[j, i]合法的条件是sum[i] - sum[j - 1] - (sum[x] - sum[x - d]) <= p. 复杂度: 时间复杂度:因为每个点最多遍历2次,复杂度为O(n). 空间复杂度:O(n) RE: 更新j的时候忘写h <= t了.如果写对拍的话应该可以拍出来. GET: 如果

4385: [POI2015]Wilcze do?y

原题:http://www.lydsy.com/JudgeOnline/problem.php?id=4385 Description 给定一个长度为n的序列,你有一次机会选中一段连续的长度不超过d的区间,将里面所有数字全部修改为0.请找到最长的一段连续区间,使得该区间内所有数字之和不超过p. Input 第一行包含三个整数n,p,d(1<=d<=n<=2000000,0<=p<=10^16).第二行包含n个正整数,依次表示序列中每个数w[i](1<=w[i]<=

@bzoj - [email&#160;protected] [POI2015] Wilcze do?y

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定一个长度为 n 的序列,你有一次机会选中一段连续的长度不超过 d 的区间,将里面所有数字全部修改为 0. 请找到最长的一段连续区间,使得该区间内所有数字之和不超过 p . input 第一行包含三个整数 n, p, d (1 <= d <= n <= 2000000,0 &

微信 {&quot;errcode&quot;:40029,&quot;errmsg&quot;:&quot;invalid code, hints: [ req_id: Cf.y.a0389s108 ]&quot;}

{"errcode":40029,"errmsg":"invalid code, hints: [ req_id: Cf.y.a0389s108 ]"} 问题:微信网页授权后,获取到 openid 了,一刷新又没了 微信网页授权获取到的 code 只能使用一次(5分钟内有效),使用一次后,马上失效. 页面授权跳转成功,根据 code 也换取到 openid 了. 此时刷新页面,并不会再次进行授权,而是直接刷新了一下上一次授权跳转后的链接,带的还是

[hihoCoder#1381]Little Y&#39;s Tree

[hihoCoder#1381]Little Y's Tree 试题描述 小Y有一棵n个节点的树,每条边都有正的边权. 小J有q个询问,每次小J会删掉这个树中的k条边,这棵树被分成k+1个连通块.小J想知道每个连通块中最远点对距离的和. 这里的询问是互相独立的,即每次都是在小Y的原树上进行操作. 输入 第一行一个整数n,接下来n-1行每行三个整数u,v,w,其中第i行表示第i条边边权为wi,连接了ui,vi两点. 接下来一行一个整数q,表示有q组询问. 对于每组询问,第一行一个正整数k,接下来一

机械随笔(y一)

过去最巧秒的机械往往是机械对机械自身的控制,然而现在往往只要一块电路板就行了(有点无奈). 可爱可畏的机电一体化. 人类社会第一个巨大进步,效率生产力的极大提高,人口的井喷来自工业革命,来自对钢铁肌肉的力量的首次挖掘利用.而今全球互联网的沟通促成的信息无限交流并未最大限度地提升人类生产力(更不用说某些的商业方面的模式创新).信息的交流是为生产力的提升打下坚实基础,当然强大的云计算也应该是未来生产变革中不可或缺的一环.最终的发展仍然要落实到制造的本体上,毕竟现在的人不可能靠数据流生活,很长很长一段