洛谷 P3594 [POI2015]WIL-Wilcze doły 题解

题目链接

以前听人讲过,现在全都忘了QwQ,特此写一个题解

首先,为了选到的区间尽可能的长,我们要把该的区间中尽可能多的数变为 0 0 0,并且满足消掉的数字和尽可能大。

我们考虑用双指针维护区间 [ l , r ] [l,r] [l,r],并且用一个单调队列维护该区间中的长度为 d d d 的 区间,满足这些区间和单调递减。
那么,如果 s u m ( l , r ) − s u m ( 删 去 的 区 间 ) < p sum(l,r)-sum(删去的区间)<p sum(l,r)sum()<p,则 ++r,否则 ++l

#include<cstdio>
#include<iostream>
#include<deque>
using namespace std;
const long long Maxn=2000000+10,inf=0x3f3f3f3f;
deque <long long> q;
long long n,m,k,ans;
long long a[Maxn],s[Maxn];
int main()
{
    
    
//	freopen("in.txt","r",stdin);
	scanf("%lld%lld%lld",&n,&k,&m);
	for(long long i=1;i<=n;++i)
	{
    
    
		scanf("%lld",a+i);
		s[i]=s[i-1]+a[i];
	}
	if(n<=m)
	{
    
    
		cout<<n<<endl;
		return 0;
	}
	long long l=1,r=min(n,m);
	q.push_back(1);
	while(l<=n && r<=n)
	{
    
    
		while(q.size() && q.front()<l)q.pop_front();
		long long i=q.front();
		if(s[r]-s[l-1]-(s[min(i+m-1,r)]-s[i-1])>k && r-l+1>m){
    
    ++l;continue;}
		ans=max(ans,r-l+1);
		++r;
		while(q.size() && s[q.back()+m-1]-s[q.back()-1]<=s[r]-s[r-m])
		q.pop_back();
		q.push_back(r-m+1);
	}
	printf("%lld\n",ans);
}

猜你喜欢

转载自blog.csdn.net/Brian_Pan_/article/details/107807513