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

poi2015 bzoj4377-4386训练

4385: [POI2015]Wilcze do?y

P3594 [POI2015]WIL-Wilcze do?y

bzoj4385 & POJ2015 Wilcze do?y