P3950 部落冲突

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

const int N=3e5+5;

int f[N],c[N][2];
bool rev[N];
int st[N],t;

inline bool get(int x)
{
    return c[f[x]][1]==x;
}

inline bool nroot(int x)
{
    return c[f[x]][0]==x||c[f[x]][1]==x;
}

inline void pushrev(int x)
{
    if(!rev[x])
        return;
    swap(c[x][0],c[x][1]);
    if(c[x][0])
        rev[c[x][0]]^=1;
    if(c[x][1])
        rev[c[x][1]]^=1;
    rev[x]=0;
}

inline void rotate(int x)
{
    int y=f[x],z=f[y],k=get(x),w=c[x][!k];
    if(z&&nroot(y))
        c[z][get(y)]=x;
    c[y][k]=w,c[x][!k]=y;
    if(w)
        f[w]=y;
    f[x]=z,f[y]=x;
}

inline void splay(int x)
{
    int y;
    st[t=1]=x;
    for(y=x;nroot(y);y=f[y])
        st[++t]=f[y];
    for(;t;--t)
        pushrev(st[t]);
    while(nroot(x))
    {
        y=f[x];
        if(nroot(y))
            rotate(get(y)^get(x)?x:y);
        rotate(x);
    }
}

inline void access(int x)
{
    for(int y=0;x;x=f[y=x])
        splay(x),c[x][1]=y;
}

inline void makeroot(int x)
{
    access(x),splay(x);
    rev[x]^=1;
}

inline int findroot(int x)
{
    access(x),splay(x);
    for(pushrev(x);c[x][0];pushrev(x))
        x=c[x][0];
    splay(x);
    return x;
}

inline void link(int x,int y)
{
    makeroot(x);
    f[x]=y;
}

inline void cut(int x,int y)
{
    makeroot(x);
    access(y),splay(y);
    f[x]=c[y][0]=0;
}

int n,m;
int a[N],b[N],tim;
char opt[10];
int main()
{    
    scanf("%d%d",&n,&m);
    for(int i=1,x,y;i<n;++i)
    {
        scanf("%d%d",&x,&y);
        link(x,y);
    }
    for(int i=1,x,y;i<=m;++i)
    {
        scanf("%s",opt);
        if(opt[0]=='Q')
        {
            scanf("%d%d",&x,&y);
            if(findroot(x)==findroot(y))
                puts("Yes");
            else
                puts("No");
        }
        else if(opt[0]=='C')
        {
            ++tim;
            scanf("%d%d",&a[tim],&b[tim]);
//            cout<<a[tim]<<" "<<b[tim]<<endl;
            cut(a[tim],b[tim]);
        }
        else
        {
            scanf("%d",&x);
            link(a[x],b[x]);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/lovewhy/p/9633847.html