P3950 部落冲突
// luogu-judger-enable-o2 #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int N=3e5+5; int f[N],c[N][2]; 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[y][k]=w,c[x][!k]=y; if(w) f[w]=y; f[x]=z,f[y]=x; } inline void splay(int x) { int y; 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]; if(nroot(y)) rotate(get(y)^get(x)?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); f[x]=c[y][0]=0; } int n,m; int a[N],b[N],tim; char opt[10]; int main() { scanf("%d%d",&n,&m); for(int i=1,x,y;i<n;++i) { scanf("%d%d",&x,&y); link(x,y); } for(int i=1,x,y;i<=m;++i) { scanf("%s",opt); if(opt[0]=='Q') { scanf("%d%d",&x,&y); if(findroot(x)==findroot(y)) puts("Yes"); else puts("No"); } else if(opt[0]=='C') { ++tim; scanf("%d%d",&a[tim],&b[tim]); // cout<<a[tim]<<" "<<b[tim]<<endl; cut(a[tim],b[tim]); } else { scanf("%d",&x); link(a[x],b[x]); } } return 0; }