BZOJ 4825 [Hnoi2017]单旋

Posted ws_zzy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 4825 [Hnoi2017]单旋相关的知识,希望对你有一定的参考价值。

题解:LCT维护Splay形态

Splay后发现只会有几个点发生变化,用LCT维护一下就可以了

在Splay中维护siz

还可以用Splay维护DFS序,旋转后DFS序不变,深度以子树为单位变化

天真的我以为直接模拟Splay可以A掉QWQ

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
const int maxn=100009;

int T;
map<int,int>ma;
int tfa[maxn],tch[maxn][2];

int root,nn;
int fa[maxn],ch[maxn][2],siz[maxn],rev[maxn];
inline int son(int x){
	if(ch[fa[x]][1]==x)return 1;
	else return 0;
}
inline void pushup(int x){
	siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
}
inline bool isroot(int x){
	return (ch[fa[x]][0]!=x)&&(ch[fa[x]][1]!=x);
}
inline void pushdown(int x){
	if(rev[x]){
		rev[ch[x][0]]^=1;
		rev[ch[x][1]]^=1;
		rev[x]^=1;
		swap(ch[x][0],ch[x][1]);
	}
}
void Downfa(int x){
	if(!isroot(x))Downfa(fa[x]);
	pushdown(x);
}

inline void Rotate(int x){
	int y=fa[x];
	int z=fa[y];
	int b=son(x),c=son(y);
	int a=ch[x][b^1];
	if(!isroot(y))ch[z][c]=x;
	fa[x]=z;
	if(a)fa[a]=y;
	ch[y][b]=a;
	fa[y]=x;ch[x][b^1]=y;
	pushup(y);pushup(x);
}

void Splay(int x){
	Downfa(x);
	while(!isroot(x)){
		int y=fa[x];
		if(isroot(y)){
			Rotate(x);
		}else{
			if(son(x)==son(y)){
				Rotate(y);Rotate(x);
			}else{
				Rotate(x);Rotate(x);
			}
		}
	}
}

void Access(int x){
	for(int t=0;x;t=x,x=fa[x]){
		Splay(x);ch[x][1]=t;pushup(x);
	}
}
void Makeroot(int x){
	Access(x);Splay(x);rev[x]^=1;
}
void Linkp(int x,int y){
	Makeroot(x);fa[x]=y;
}
void Cutp(int x,int y){
	Makeroot(x);Access(y);Splay(y);
	fa[ch[y][0]]=0;ch[y][0]=0;pushup(y);
}

int Getdep(int x){
	Access(x);Splay(x);return siz[x];
}

int main(){
	scanf("%d",&T);
	while(T--){
		if(root)Makeroot(root);
		int opty,x;
		scanf("%d",&opty);
		if(opty==1){
			scanf("%d",&x);
			ma[x]=++nn;siz[nn]=1;
			if(root==0){
				root=nn;
			}else{
				map<int,int>::iterator it1=ma.lower_bound(x);
				map<int,int>::iterator it2=ma.upper_bound(x);
				if(it1==ma.begin()){//只有后继
					Linkp(nn,it2->second);
					tfa[nn]=it2->second;
					tch[it2->second][0]=nn;
				}else if(it2==ma.end()){//只有前驱 
					--it1;
					Linkp(nn,it1->second);
					tfa[nn]=it1->second;
					tch[it1->second][1]=nn;
				}else{
					--it1;
					int dep1=Getdep(it1->second);
					int dep2=Getdep(it2->second);
					if(dep1>dep2){
						Linkp(nn,it1->second);
						tfa[nn]=it1->second;
						tch[it1->second][1]=nn;
					}else{
						Linkp(nn,it2->second);
						tfa[nn]=it2->second;
						tch[it2->second][0]=nn;
					}
				}
			}
			printf("%d\n",Getdep(nn));
		}
		if(opty==4){
			map<int,int>::iterator it=ma.begin();
			int x=it->second;
			printf("%d\n",Getdep(x));
			if(x==root){
				root=tch[x][1];
				tfa[tch[x][1]]=0;
				if(tch[x][1])Cutp(tch[x][1],x);
			}else{
				Cutp(x,tfa[x]);
				tch[tfa[x]][0]=0;
				int y=tch[x][1];
				if(y){
					Cutp(x,y);
					Linkp(tfa[x],y);
					tfa[y]=tfa[x];
					tch[tfa[x]][0]=y;
				}
			}
			ma.erase(it->first);
		}
		if(opty==5){
			map<int,int>::iterator it=ma.end();--it;
			int x=it->second;
			printf("%d\n",Getdep(x));
			if(x==root){
				root=tch[x][0];
				tfa[tch[x][0]]=0;
				if(tch[x][0])Cutp(tch[x][0],x);
			}else{
				Cutp(x,tfa[x]);
				tch[tfa[x]][1]=0;
				int y=tch[x][0];
				if(y){
					Cutp(x,y);
					Linkp(tfa[x],y);
					tfa[y]=tfa[x];
					tch[tfa[x]][1]=y;
				}
			}
			ma.erase(it->first);
		}
		if(opty==2){
			map<int,int>::iterator it=ma.begin();
			int x=it->second;
			printf("%d\n",Getdep(x));
			if(x==root){
			}else{
				Cutp(x,tfa[x]);
				tch[tfa[x]][0]=0;
				int y=tch[x][1];
				if(y){
					Cutp(x,y);
					Linkp(tfa[x],y);
					tfa[y]=tfa[x];
					tch[tfa[x]][0]=y;
				}
				Linkp(root,x);
				tfa[x]=0;tch[x][1]=root;
				tfa[root]=x;root=x;
			}
		}
		if(opty==3){
			map<int,int>::iterator it=ma.end();--it;
			int x=it->second;
			printf("%d\n",Getdep(x));
			if(x==root){
			}else{
				Cutp(x,tfa[x]);
				tch[tfa[x]][1]=0;
				int y=tch[x][0];
				if(y){
					Cutp(x,y);
					Linkp(tfa[x],y);
					tfa[y]=tfa[x];
					tch[tfa[x]][1]=y;
				}
				Linkp(root,x);
				tfa[x]=0;tch[x][0]=root;
				tfa[root]=x;root=x;
			}
		}
	}
	return 0;
}

  

以上是关于BZOJ 4825 [Hnoi2017]单旋的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ4825[Hnoi2017]单旋 线段树+set

bzoj4825 [Hnoi2017]单旋

[2017.11.29]BZOJ4825[Hnoi2017]单旋

BZOJ 4825 [Hnoi2017]单旋

BZOJ4825HNOI2017单旋(Link-Cut Tree)

BZOJ4825 单旋