数据说明 10%的数据满足n≤1000, m≤20000 20%的数据满足n≤2000, m≤40000 30%的数据满足n≤3000, m≤60000 40%的数据满足n≤4000, m≤80000 50%的数据满足n≤5000, m≤100000 60%的数据满足n≤6000, m≤120000 70%的数据满足n≤7000, m≤140000 80%的数据满足n≤8000, m≤160000 90%的数据满足n≤9000, m≤180000 100%的数据满足n≤10000, m≤200000 保证所有Destroy指令将摧毁的是一条存在的通道本题输入、输出规模比较大,建议c\c++选手使用scanf和printf进行I\O操作以免超时
#include<cstdio>
const int maxn=1e4+10;
inline void swap_(int&x,int&y){x^=y,y^=x,x^=y;}
int n,m;
int f[maxn],s[maxn][2],t[maxn],v[maxn];
bool isroot(int x){return s[f[x]][0]!=x&&s[f[x]][1]!=x;}
void pushdown(int x){
int ls=s[x][0],rs=s[x][1];
v[ls]^=1,v[rs]^=1,v[x]^=1;
swap_(s[x][0],s[x][1]);
}
void rotate(int x){
int y=f[x],z=f[y],l,r;
l=s[y][0]==x?0:1,r=l^=1;
if(!isroot(y)){
if(s[z][0]==y) s[z][0]=x;
else s[z][1]=x;
}
f[x]=z,f[y]=x,f[s[x][r]]=y;
s[y][l]=s[x][r],s[x][r]=y;
}
void splay(int x){
int top=0;
t[++top]=x;
for(int i=x;!isroot(i);i=f[i]) t[++top]=f[i];
for(int i=top;i;i--) if(v[t[i]]) pushdown(t[i]);
}
void access(int x){
int t=0;
while(x){
splay(x);
s[x][1]=t,t=x,x=f[x];
}
}
void makeroot(int x){
access(x);
splay(x);
v[x]^=1;
}
void join(int x,int y){
makeroot(x);
f[x]=y;
splay(x);
}
void cut(int x,int y){
makeroot(x);
access(y);
splay(y);
s[y][0]=f[x]=0;
}
int find(int x){
access(x);
splay(x);
int y=x;
while(s[y][0]) y=s[y][0];
return y;
}
int main(){
char ch[10];
int x,y;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%s%d%d",ch,&x,&y);
if(ch[0]==‘C‘) join(x,y);
if(ch[0]==‘D‘) cut(x,y);
if(ch[0]==‘Q‘){
if(find(x)==find(y)) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}