【codevs4655】序列终结者(平衡树splay)

题目:

我是超链接

题解:

基本是模板题,维护区间最大值

记住build的时候update以及时刻pushdown

多update几下不会错的-------天宇哥哥

代码:

#include 
#include 
#include 
#define N 50000
#define INF 1e9
using namespace std;
int ch[N+5][2],f[N+5],maxn[N+5],size[N+5],key[N+5],delta[N+5],deltafz[N+5],root,sz,a[N+5];
int get(int x){return ch[f[x]][1]==x;}
void updata(int x)
{
	if (x)
	{
		maxn[x]=key[x];
		if (ch[x][0]) maxn[x]=max(maxn[x],maxn[ch[x][0]]);
		if (ch[x][1]) maxn[x]=max(maxn[x],maxn[ch[x][1]]);
		size[x]=1;
		if (ch[x][0]) size[x]+=size[ch[x][0]];
		if (ch[x][1]) size[x]+=size[ch[x][1]];	
	} 
}
void pushdown(int x)
{
	if (delta[x])
	{
		if (ch[x][0]) delta[ch[x][0]]+=delta[x],key[ch[x][0]]+=delta[x],maxn[ch[x][0]]+=delta[x];
		if (ch[x][1]) delta[ch[x][1]]+=delta[x],key[ch[x][1]]+=delta[x],maxn[ch[x][1]]+=delta[x];
		delta[x]=0;
	}
	if (deltafz[x])
	{
		deltafz[x]=0;
		swap(ch[x][1],ch[x][0]);
		if (ch[x][0]) deltafz[ch[x][0]]^=1;
		if (ch[x][1]) deltafz[ch[x][1]]^=1;
	}
}
void rotate(int x)
{
	pushdown(f[x]);
	pushdown(x);
	int old=f[x],oldf=f[old],which=get(x);
	ch[old][which]=ch[x][which^1]; f[ch[x][which^1]]=old;
	ch[x][which^1]=old; f[old]=x;
	f[x]=oldf;
	if (oldf) ch[oldf][ch[oldf][1]==old]=x;
	updata(old);
	updata(x);	
}
void splay(int x,int tar)
{
	for (int fa;(fa=f[x])!=tar;rotate(x))
	  if (f[fa]!=tar) rotate(get(x)==get(fa)?fa:x);
	if (tar==0) root=x;
}
int build(int fa,int l,int r)
{
	if (l>r) return 0;
	int mid=(l+r)>>1;
	int now=++sz; size[now]=1; f[now]=fa; key[now]=maxn[now]=a[mid];
	int lch=build(now,l,mid-1);
	int rch=build(now,mid+1,r);
	ch[now][0]=lch; ch[now][1]=rch;
	updata(now);
	return now;
}
int find(int x)
{
	int now=root;
	while (1)
	{
		pushdown(now);
		if (ch[now][0] && x<=size[ch[now][0]]) now=ch[now][0];
		else 
		{
			x-=size[ch[now][0]]+1;
			if (!x) return now;
			now=ch[now][1];
		}
	}
}
int main()
{
	int n,m,i;
	scanf("%d%d",&n,&m); 
	a[1]=-INF; a[n+2]=INF;
	root=build(0,1,n+2);
	for (i=1;i<=m;i++)
	{
		int opt,l,r,v;
		scanf("%d",&opt);	
		scanf("%d%d",&l,&r);
		int a1=find(l),a2=find(r+2);
		splay(a1,0);
		splay(a2,a1);	
		if (opt==1)
		{
			scanf("%d",&v);
			delta[ch[ch[root][1]][0]]+=v;
			maxn[ch[ch[root][1]][0]]+=v;
			key[ch[ch[root][1]][0]]+=v;
			updata(ch[root][1]);
			updata(root);
		}
		else
		  if (opt==2)
		    deltafz[ch[ch[a1][1]][0]]^=1;
		else
		  printf("%d\n",maxn[ch[ch[a1][1]][0]]);
	}
}


你可能感兴趣的:(平衡树)