LCT或者按秩合并的并查集维护一下联通性就行了。。
LCT:
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=10005,MAX=999999999;
int c[maxn][2],pre[maxn],isroot[maxn],rev[maxn],n,m,u,v,i;
char com[10];
void mark(int x)
{if (!x) return;
swap(c[x][0],c[x][1]);
rev[x]^=1;
}
void update(int x)
{if (rev[x])
{mark(c[x][0]);mark(c[x][1]);
rev[x]=0;
}
}
void rotate(int x,int kind)
{int y=pre[x],z=pre[y];
update(y);update(x);
pre[y]=x;pre[x]=z;
c[y][!kind]=c[x][kind];
pre[c[x][kind]]=y;
c[x][kind]=y;
if (z&&!isroot[y]) c[z][c[z][1]==y]=x;
if (isroot[y])
{isroot[y]=0;
isroot[x]=1;
}
}
void splay(int x)
{update(x);
while (!isroot[x])
{//printf("%d %d %d %d %d %d\n",x,pre[x],c[x][0],c[x][1],rev[x],isroot[x]);
int y=pre[x],z=pre[y];
if (z) update(z);
update(y);
if (isroot[y]) rotate(x,c[y][0]==x);
else
{int kind=c[y][0]==x;
if (c[z][kind]==y)
{rotate(x,kind);
rotate(x,!kind);
}
else
{rotate(y,kind);
rotate(x,kind);
}
}
}
}
void access(int x)
{splay(x);
update(x);
if (c[x][1]) isroot[c[x][1]]=1;
c[x][1]=0;
int u;
while (pre[x])
{u=pre[x];
splay(u);
if (c[u][1]) isroot[c[u][1]]=1;
c[u][1]=x;
isroot[x]=0;
splay(x);
}
}
void evert(int x)
{access(x);
splay(x);
mark(x);
}
void cut(int x,int y)
{access(x);
splay(x);
int fa;
update(x);
fa=c[x][0];
while (c[fa][1])
{update(fa);
fa=c[fa][1];
}
if (fa==y) swap(x,y);
access(y);
splay(y);
if (c[y][0])
{isroot[c[y][0]]=1;
pre[c[y][0]]=pre[y];
}
c[y][0]=0;
}
void join(int y,int x)
{evert(x);
access(x);
splay(x);
pre[x]=y;
//access(x);
}
int getroot(int x)
{access(x);
splay(x);
while (c[x][0])
{update(x);
x=c[x][0];
}
splay(x);
return x;
}
void work(int x,int y)
{int rx=getroot(x),ry=getroot(y);
if (rx==ry) printf("Yes\n"); else printf("No\n");
}
int main()
{freopen("cave.in","r",stdin);
//freopen("cave.out","w",stdout);
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
{isroot[i]=1;
c[i][1]=c[i][0]=pre[i]=rev[i]=0;
}
for (i=1;i<=m;i++)
{scanf("%s%d%d",&com,&u,&v);
if (com[0]=='C') join(u,v);
if (com[0]=='D') cut(u,v);
if (com[0]=='Q') work(u,v);
// for (int j=1;j<=n;j++)
// printf("%d*%d %d %d %d %d %d\n",i,j,pre[j],c[j][0],c[j][1],rev[j],isroot[j]);
}
fclose(stdin);
//fclose(stdout);
}