bzoj 2049: [Sdoi2008]Cave 洞穴勘测
http://www.lydsy.com/JudgeOnline/problem.php?id=2049
大约是lct的模板题,打不挂就能过,开始rotate写挂了QAQ
#include<cstdio> #include<iostream> const int maxn = 600007; int n,m; int top=0; int ch[maxn][2],fa[maxn],stack[maxn]; bool rev[maxn]; inline int read() { int x=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c<='9'&&c>='0') x=x*10+c-'0',c=getchar(); return x; } bool isroot(int x) { return ch[fa[x]][1]!=x&&ch[fa[x]][0]!=x; } void pushdown(int x) { if(rev[x]) { rev[x]^=1; rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;std::swap(ch[x][1],ch[x][0]); } } void rotate(int x) { int y=fa[x],z=fa[y],d=(ch[y][1]==x)^1; if(!isroot(y)) ch[z][ch[z][1]==y]=x; fa[x]=z; ch[y][d^1]=ch[x][d],fa[ch[x][d]]=y; ch[x][d]=y;fa[y]=x; } void splay(int x) { stack[++top]=x; for(int i=x;!isroot(i);i=fa[i]) stack[++top]=fa[i]; while(top)pushdown(stack[top--]); while(!isroot(x)) { int y=fa[x],z=fa[y]; if(!isroot(y)) { if(ch[y][1]==x^ch[z][1]==y)rotate(x); else rotate(y); } rotate(x); } return ; } void access(int x) { for(int i=0;x;i=x,x=fa[x]) { splay(x); ch[x][1]=i; } } void makeroot(int x) { access(x),splay(x);rev[x]^=1; } void cut(int x,int y) { makeroot(x),access(y),splay(y); ch[y][0]=fa[x]=0; } void link(int x,int y) { makeroot(x),fa[x]=y;return splay(x); } int find(int x) { for(access(x),splay(x);ch[x][0];x=ch[x][0]) ; return x; } int main() { n=read(),m=read(); char c[30]; for(int a,b;m;m--) { scanf("%s",c),a=read(),b=read(); if(c[0]=='Q') { if(find(a)==find(b))puts("Yes"); //printf("%d %d\n",po,qq); else puts("No"); } else if(c[0]=='C') link(a,b); else cut(a,b); } return 0; }