BZOJ4385: [POI2015]Wilcze doły

水题。。

反正就是丢到一个单调队列里去然后每次都弹出就好了。。

#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;

char c;
inline void read(int &a)
{
	a=0;do c=getchar();while(c<'0'||c>'9');
	while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
#define ll long long
inline void read(ll &a)
{
	a=0;do c=getchar();while(c<'0'||c>'9');
	while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
inline int max(int a,int b){return a>b?a:b;}
ll  Sum[2000001];
ll Sum2[2000001];
ll  Max[2000001];
int Data[2000001];
struct St
{int data,l;};
St Stack[2000001];
int con,fir;
int n,d;
ll p;
inline void push(int x,int data)
{
	while(con>=fir&&data>Stack[con].data)
	   con--;
	Stack[++con].l=x;
	Stack[con].data=data	;
}
inline void pop(int x)
{
   if(Stack[fir].l<=x-d)
      fir++;
} 
int L,R;
int main()
{

	read(n);
	read(p);
	read(d);
	fir=1;
	for(int i=1;i<=n;i++)
	 read(Data[i]),Sum[i]=Sum[i-1]+Data[i],Sum2[i]=Sum[i]-Sum[max(0,i-d)];

	fir=1;con=0;
	int ans=d;
	push(1,Sum2[d]);
	L=1;
	for(int i=d+1;i<=n;i++)
	   {
		  push(i-d+1,Sum2[i]); 
	      while(Sum[i]-Sum[L-1]>(ll)Stack[fir].data+p) 
	          {
	          	L++;
	          	if(Stack[fir].l<L)fir++;
	          }
	      ans=max(ans,i-L+1); 
	   } 
	printf("%d\n",ans);
	
	return 0;
}
 


你可能感兴趣的:(bzoj)