BZOJ 4385 洛谷3594 POI2015 WIL-Wilcze do?y
Posted Driver_Lao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 4385 洛谷3594 POI2015 WIL-Wilcze do?y相关的知识,希望对你有一定的参考价值。
【题解】
手残写错调了好久QAQ......
洛谷的数据似乎比较水。。
n个正整数!!这很重要
这道题是个类似two pointer的思想,外加一个单调队列维护当前区间内长度为d的子序列中元素之和的最大值。
枚举右端点,如果左端点到右端点的元素和减去区间内长为d的子序列中元素和的最大值,大于给定的P,那么就把左端点向右挪。
#include<cstdio> #include<algorithm> #define N 2000010 #define rg register #define LL long long using namespace std; LL n,m,d,a[N],h[N],s[N],p[N],tmp; int ans; inline LL read(){ LL k=0; char c=getchar(); while(c<\'0\'||c>\'9\')c=getchar(); while(\'0\'<=c&&c<=\'9\')k=k*10+c-\'0\',c=getchar(); return k; } inline int max(int x,int y){ return x>y?x:y; } int main(){ n=read(); m=read(); ans=d=read(); for(rg int i=1;i<=n;i++) a[i]=read(),s[i]=s[i-1]+a[i]; if(n<=d) return printf("%d\\n",d),0; int l=1,front=1,rear=0; for(rg int i=d+1;i<=n;i++){ tmp=s[i]-s[i-d]; while(front<=rear&&h[rear]<=tmp) rear--; h[++rear]=tmp; p[rear]=i-d+1; while(p[front]<l&&front<=rear) front++; while(l<=i-d+1){ if(front<=rear) tmp=s[i]-s[l-1]-h[front]; else tmp=s[i]-s[l-1]; if(tmp<=m){ ans=max(ans,i-l+1); break; } else l++; } tmp=s[i]-s[l-1]; } printf("%d\\n",ans); return 0; }
以上是关于BZOJ 4385 洛谷3594 POI2015 WIL-Wilcze do?y的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 4385: [POI2015]Wilcze do?y
@bzoj - 4385@ [POI2015] Wilcze do?y