1. 程式人生 > >BZOJ:2049: [Sdoi2008]Cave 洞穴勘測

BZOJ:2049: [Sdoi2008]Cave 洞穴勘測

for pushd ems oot splay while return clu %d

題解:

LinkCutTree維護連通性

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

const int maxn=100009;

int n,m;

int fa[maxn],ch[maxn][2],rev[maxn];
int minit(){
	memset(fa,0,sizeof(fa));
	memset(ch,0,sizeof(ch));
	memset(rev,0,sizeof(rev));
}

inline int son(int x){
	return ch[fa[x]][1]==x;
}
inline int isroot(int x){
	return (ch[fa[x]][1]!=x)&&(ch[fa[x]][0]!=x);
}
inline int 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]);
	}
}
int Down(int x){
	if(!isroot(x))Down(fa[x]);
	pushdown(x);
}

int 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;
}

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

int Access(int x){
	for(int t=0;x;t=x,x=fa[x]){
		Splay(x);ch[x][1]=t;
	}
}

int Evert(int x){
	Access(x);Splay(x);rev[x]^=1;
}

int Link(int x,int y){
	Evert(x);fa[x]=y;
}

int Cut(int x,int y){
	Evert(x);Access(y);Splay(y);
	fa[ch[y][0]]=0;ch[y][0]=0;
}

int getf(int x){
	Access(x);Splay(x);
	while(ch[x][0])x=ch[x][0];
	return x;
}

int main(){
	minit();
	scanf("%d%d",&n,&m);
	char opty[10];
	while(m--){
		scanf("%s",opty);
		int x,y;
		scanf("%d%d",&x,&y);
		if(opty[0]==‘Q‘){
			if(getf(x)==getf(y))printf("Yes\n");
			else printf("No\n");
		}
		if(opty[0]==‘C‘){
			Link(x,y);
		}
		if(opty[0]==‘D‘){
			Cut(x,y);
		}
	}
	return 0;
}

  

BZOJ:2049: [Sdoi2008]Cave 洞穴勘測