BZOJ4491 我也不知道题目名字是什么

我也不知道题目名字是什么。

啊啊啊啊啊这题好难啊我不会做

竟然没有修改操作

先差分一下数组,每个点存它和前一个/后一个的差值,题目转化成求最长的连续元素>=0的长度

这就辣鸡东西了

注意l==r时的特判

// It is made by XZZ
#include<cstdio>
#include<algorithm>
#define il inline
#define rg register
#define vd void
#define sta static
il int gi(){
	rg int x=0,f=1;rg char ch=getchar();
	while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*f;
}
const int maxn=50001;
int w[maxn],W[maxn];
struct node{int siz,maxl,maxr,ans;};
node operator +(const node&a,const node&b){
	node c;
	c.siz=a.siz+b.siz;
	if(a.maxl==a.siz)c.maxl=a.maxl+b.maxl;
	else c.maxl=a.maxl;
	if(b.maxr==b.siz)c.maxr=a.maxr+b.maxr;
	else c.maxr=b.maxr;
	c.ans=std::max(std::max(a.ans,b.ans),a.maxr+b.maxl);
	return c;
}
struct sgt{
#define mid ((l+r)>>1)
#define ls (x<<1)
#define rs (x<<1|1)
	node s[maxn<<2];
	il vd build(int x,int l,int r){
		if(l==r){
			s[x].siz=1;
			if(W[l]>=0)s[x].maxl=s[x].maxr=s[x].ans=1;
			else s[x].maxl=s[x].maxr=s[x].ans=0;
			return;
		}
		build(ls,l,mid);build(rs,mid+1,r);
		s[x]=s[ls]+s[rs];
	}
	il node Query(int x,int l,int r,int ll,int rr){
		if(ll<=l&&r<=rr)return s[x];
		if(ll<=mid)
			if(rr>mid)return Query(ls,l,mid,ll,rr)+Query(rs,mid+1,r,ll,rr);
			else return Query(ls,l,mid,ll,rr);
		else return Query(rs,mid+1,r,ll,rr);
	}
#undef mid
#undef ls
#undef rs
};
sgt A,B;
int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	int n=gi(),m;
	for(rg int i=1;i<=n;++i)w[i]=gi();
	for(rg int i=1;i<=n;++i)W[i]=w[i]-w[i-1];
	A.build(1,1,n);
	for(rg int i=1;i<=n;++i)W[i]=w[i]-w[i+1];
	B.build(1,1,n);
	int l,r;m=gi();
	while(m--){
		l=gi(),r=gi();
		if(l==r)puts("1");
		else printf("%d
",1+std::max(A.Query(1,1,n,l+1,r).ans,B.Query(1,1,n,l,r-1).ans));
	}
	return 0;
}
原文地址:https://www.cnblogs.com/xzz_233/p/bzoj4491.html