首页 > 其他分享 >P3594 WIL

P3594 WIL

时间:2022-11-11 10:48:27浏览次数:60  
标签:右移 int sum WIL 队列 P3594 区间 指针

P3594 WIL

题意很简化了已经

刚拿到题的时候我其实想的就是在一段大区间(答案区间)中找到长度为d的区间最大的区间,然后答案就是大区间的区间和减去长度为d的区间和,这个大区间找的时候用双指针,r一直右移,如果区间和减去长度为d的区间和大于了p,那左指针就右移,就这样一直找;

但是有两个问题,就是我怎么找这个大区间中长为d的最大区间,可以先提前预处理前缀和,sum[r]-sum[r-d]就是你要维护的值,而单调队列离要存下标(因为后边要用),另一个问题是,如果大区间左指针右移之后,你本来维护的那个长为d的区间就出了大区间了,那怎么解决?(我当时就是因为单调队列存的不是下标,然后就不会搞了,因为我没法判断它是不是出了大区间)因为单调队列存的是下标,所以,每次左指针右移时,都要while判断你存的那个区间是不是小于左指针即可,如果小于,那单调队列就出队头;

每次新加一个数都统计最大区间长度即可

下面是代码

#include<bits/stdc++.h>
using namespace std;
#define int long long

const int N=2e6+10;
int n,p,d;
int q[N],a[N],ans,l,sum[N],t,h;

signed main()
{
	cin>>n>>p>>d;
	for(int i=1;i<=n;i++)scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];
	ans=d,q[t]=d,l=1;
	for(int i=d+1;i<=n;i++)
	{
		while(h<=t&&sum[i]-sum[i-d]>sum[q[t]]-sum[q[t]-d])--t;
		q[++t]=i;
		while(h<=t&&sum[i]-sum[l-1]-sum[q[h]]+sum[q[h]-d]>p)
		{
			++l;
			while(h<=t&&q[h]-d+1<l)++h;
		}
		ans = max(ans,i-l+1);
	}
	printf("%lld", ans);
	return 0;
}

标签:右移,int,sum,WIL,队列,P3594,区间,指针
From: https://www.cnblogs.com/Eternal-QX/p/16879768.html

相关文章