数据说明 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操作以免超时
/**************************************************************
Problem: 2049
User: weeping
Language: C++
Result: Accepted
Time:1936 ms
Memory:3644 kb
****************************************************************/
#include <bits/stdc++.h>
using namespace std;
struct Link_Cut_Tree
{
static const int MAXN = 100000 + 7;
int ch[MAXN][2], fa[MAXN], rev[MAXN], sz[MAXN];
int sk[MAXN];
bool isroot(int x)
{
return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
}
void reverse(int x)
{
rev[x] ^= 1, swap(ch[x][0],ch[x][1]);
}
void update(int x)
{
sz[x] = ch[x][0] + ch[x][1] +1;
}
void push_down(int x)
{
if(!rev[x]) return ;
if(ch[x][0]) reverse(ch[x][0]);
if(ch[x][1]) reverse(ch[x][1]);
rev[x]=0;
}
void rotate(int x)
{
int f = fa[x], gf = fa[f];
int t1 = ( x != ch[f][0]), t2 = ( f != ch[gf][0]), tmp = ch[x][1^t1];
if(!isroot(f)) ch[gf][0^t2] = x;
fa[tmp] = f, fa[x] = gf, ch[x][1^t1] = f, fa[f] = x, ch[f][0^t1] = tmp;
update(f);
}
void splay(int x)
{
int top = 0;
sk[++top] = x;
for(int i = x; !isroot(i); i = fa[i]) sk[++top] = fa[i];
while(top) push_down(sk[top--]);
for(int f = fa[x], gf = fa[f]; !isroot(x); rotate(x), f = fa[x],gf = fa[f])
if(!isroot(f))
rotate((x==ch[f][0]) ^ (f==ch[gf][0]) ? x : f);
update(x);
}
void access(int x)
{
for(int p = 0; x; p = x, x = fa[x])
splay(x), ch[x][1] = p, update(x);
}
void makeroot(int x)
{
access(x), splay(x), reverse(x);
}
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);
if(ch[y][0] == x) ch[y][0] = fa[x] = 0;
update(y);
}
}lct;
char ss[100];
int main(void)
{
int n,m;
cin>>n>>m;
while(m--)
{
int x,y;
scanf("%s%d%d",ss,&x,&y);
if(ss[0]==‘Q‘)
{
if(lct.findroot(x)==lct.findroot(y))
printf("Yes\n");
else
printf("No\n");
}
else if(ss[0]==‘C‘)
lct.link(x,y);
else
lct.cut(x,y);
}
return 0;
}