P2147 [SDOI2008]洞穴勘测
//Pro:P2147 洞穴勘测 #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int N=1e4+5; int c[N][2],f[N]; bool rev[N]; int st[N],t; inline bool get(int x) { return c[f[x]][1]==x; } inline bool nroot(int x) { return c[f[x]][0]==x||c[f[x]][1]==x; } inline void pushrev(int x) { if(!rev[x]) return; swap(c[x][0],c[x][1]); if(c[x][0]) rev[c[x][0]]^=1; if(c[x][1]) rev[c[x][1]]^=1; rev[x]=0; } inline void rotate(int x) { int y=f[x],z=f[y],k=get(x),w=c[x][!k]; if(z&&nroot(y)) c[z][get(y)]=x; c[x][!k]=y,c[y][k]=w; if(w) f[w]=y; f[y]=x,f[x]=z; } inline void splay(int x) { int y,z; st[t=1]=x; for(y=x;nroot(y);y=f[y]) st[++t]=f[y]; for(;t;--t) pushrev(st[t]); while(nroot(x)) { y=f[x],z=f[y]; if(nroot(y)) rotate(get(x)^get(y)?x:y); rotate(x); } } inline void access(int x) { for(int y=0;x;x=f[y=x]) splay(x),c[x][1]=y; } inline void makeroot(int x) { access(x),splay(x); rev[x]^=1; } inline int findroot(int x) { access(x),splay(x); for(pushrev(x);c[x][0];pushrev(x)) x=c[x][0]; splay(x); return x; } inline void link(int x,int y) { makeroot(x); f[x]=y; } inline void cut(int x,int y) { makeroot(x); access(y),splay(y); c[y][0]=f[x]=0; } int n,m,a,b; char opt[10]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;++i) { scanf("%s",opt); scanf("%d%d",&a,&b); if(opt[0]=='Q') { if(findroot(a)==findroot(b)) puts("Yes"); else puts("No"); } else if(opt[0]=='C') link(a,b); else cut(a,b); } return 0; }