lct模板题。

#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N=10005; int fa[N],ch[N][2]; bool rev[N]; bool ck(int x) {return x==ch[fa[x]][1];} bool is_rt(int x) {return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} void rotate(int x) { int f=fa[x],ff=fa[f];bool tag=ck(x); if(!is_rt(f)) ch[ff][ck(f)]=x; ch[f][tag]=ch[x][tag^1]; fa[ch[f][tag]]=f; ch[x][tag^1]=f; fa[f]=x; fa[x]=ff; } void pushdown(int x) { if(rev[x]) { swap(ch[x][0],ch[x][1]); rev[ch[x][0]]^=1;rev[ch[x][1]]^=1; rev[x]=0; } } int top,stk[N]; void splay(int x) { stk[top=1]=x; for(int i=x;!is_rt(i);i=fa[i]) stk[++top]=fa[i]; for(int i=top;i;i--) pushdown(stk[i]); for(int f;!is_rt(x);rotate(x)) { if(!is_rt(f=fa[x])) rotate((ck(x)==ck(f))?f: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);swap(ch[x][0],ch[x][1]);rev[ch[x][1]]^=1,rev[ch[x][0]]^=1; } int findroot(int x) { access(x);splay(x); while(ch[x][0]) x=ch[x][0]; return x; } void link(int x,int y) { makeroot(x); fa[x]=y; } void cut(int x,int y) { makeroot(x);access(y);splay(y); ch[y][0]=fa[x]=0; } int n,m,x,y; char opt[10]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%s%d%d",opt,&x,&y); switch (opt[0]) { case 'C': link(x,y);break; case 'D': cut(x,y);break; case 'Q': puts(findroot(x)==findroot(y)?"Yes":"No"); } } return 0; }