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