题解:
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; }