2049: [Sdoi2008]Cave 洞穴勘测

完了真不会写LCT了。。。。。。。

还是去做几个树剖压压惊

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=10000+5;
int fa[N],ch[N][2],st[N];
bool rev[N];
inline bool isroot(int x){
	return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
}
void pushdown(int x){
	if(rev[x]){
		int l=ch[x][0],r=ch[x][1];
		swap(ch[x][0],ch[x][1]);
		rev[x]^=1;rev[l]^=1;rev[r]^=1;
	}
}
void rotate(int x){
	int y=fa[x],z=fa[y],l=ch[y][1]==x,r=l^1;
	if(!isroot(y))ch[z][ch[z][1]==y]=x;
	fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
	ch[y][l]=ch[x][r];ch[x][r]=y;
}
void splay(int x){
	int top=0;st[++top]=x;
	for(int i=x;!isroot(i);i=fa[i])st[++top]=fa[i];
	while(top)pushdown(st[top--]);
	while(!isroot(x)){
		int y=fa[x],z=fa[y];
		if(!isroot(y)){
			if(ch[y][0]==x^ch[z][0]==y)rotate(x);
			else rotate(y);
		}
		rotate(x);
	}
}
void access(int x){
	for(int t=0;x;t=x,x=fa[x])
	splay(x),ch[x][1]=t;
}
void makeroot(int x){
	access(x);splay(x);rev[x]^=1;
}
void link(int x,int y){
	makeroot(x);fa[x]=y;splay(x);
}
void cut(int x,int y){
	makeroot(x);access(y);splay(y);ch[y][0]=fa[x]=0;
}
int find(int x){
	access(x);splay(x);
	while(ch[x][0])x=ch[x][0];
	return x;
}
int main(){
	int n,m,x,y;
	scanf("%d%d",&n,&m);
	char opt[10]; 
	while(m--){
		scanf("%s%d%d",opt,&x,&y);
		if(opt[0]=='C')link(x,y);
		else if(opt[0]=='D')cut(x,y);
		else{
			if(find(x)==find(y))printf("Yes\n");
			else printf("No\n");
		}
	}
	return 0;
}


你可能感兴趣的:(2049: [Sdoi2008]Cave 洞穴勘测)