1

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 10005
using namespace std;
int n,m,u,v,qr,que[N];
struct node
{
    int fa,lc,rc,rev;
#define fa(x) t[x].fa
#define lc(x) t[x].lc
#define rc(x) t[x].rc
#define rev(x) t[x].rev
}t[N];
inline int which(const int &x)
{
    return rc(fa(x))==x;
}
inline bool isRoot(const int &x)
{
    if (!fa(x)) return 1;
    return lc(fa(x)) != x && rc(fa(x)) != x;
}
inline void downdate(const int &x)
{
    if (rev(x))
    {
    swap(lc(x),rc(x));
    if (lc(x)) rev(lc(x))^=1;
    if (rc(x)) rev(rc(x))^=1;
    rev(x)=0;
    }
    return ;
}
inline void Rotate(const int &x)
{
    int y=fa(x),z=fa(y),b=lc(y)==x?rc(x):lc(x);
    if (z && !isRoot(y)) (lc(z)==y?lc(z):rc(z))=x;
    fa(x)=z;fa(y)=x;b?fa(b)=y:0;
    if (lc(y)==x) rc(x)=y,lc(y)=b;
    else lc(x)=y,rc(y)=b;
}
inline void Splay(const int &x)
{
    que[qr=0]=x;
    for (int y=x;!isRoot(y);y=fa(y)) que[++qr]=fa(y);
    for (int i=qr;i>=0;i--) downdate(que[i]);
    while (!isRoot(x))
    {
    if (!isRoot(fa(x)))
    {
        if (which(x)==which(fa(x))) Rotate(fa(x));
        else Rotate(x);
    }
    Rotate(x);
    }
}
inline void access(int x)
{
    for (int y=0;x;y=x,x=fa(x))
    {
    Splay(x);rc(x)=y;
    if (y) fa(y)=x;
    }
}
inline int findRoot(int x)
{
    access(x);Splay(x);
    while (downdate(x),lc(x)) x=lc(x);
    Splay(x);return x;
}
inline void makeRoot(const int &x)
{
    access(x);Splay(x);
    rev(x)^=1;return;
}
inline void Link(const int &x,const int &y)
{
    makeRoot(x);fa(x)=y;
}
inline void Cut(const int &x,const int &y)
{
    makeRoot(x);access(y);Splay(y);
    lc(y)=0;fa(x)=0;
}
char ch;
inline int read()
{
    char j=getchar();int neg=1,ret=0;
    for (;j>'9' || j<'0';j=getchar())
    if (j=='-') neg=-1;
    for (;j>='0' && j<='9';j=getchar()) ret=ret*10+j-'0';
    return neg*ret;
}
int main()
{
    n=read();m=read();
    for (int i=1;i<=m;i++)
    {
    while (ch=getchar(),ch<'A' || ch>'Z');
    if (ch=='Q')
    {
        if (findRoot(read()) == findRoot(read())) puts("Yes");
        else puts("No");
    }
    else if (ch=='C') Link(read(),read());
    else Cut(read(),read());
    }
    return 0;
}

转载于:https://www.cnblogs.com/mrsheep/p/8490471.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值