bzoj 2049: [Sdoi2008]Cave 洞穴勘测

题意:

要求维护一个森林,支持加边删边,询问两点是否相连。

题解:

LCT入门题(话说高一了LCT都不会
看一下定义,这题还挺简单的。
rotate不能错。
一些不同点注意一下。
code:

#include
#include
#include
#include
using namespace std;
struct trnode{
    int fa,son[2],rev;
}tr[30005];
void update(int x)
{
    if(tr[x].rev)
    {
        int lc=tr[x].son[0],rc=tr[x].son[1];
        tr[x].rev=0;tr[lc].rev^=1;tr[rc].rev^=1;
        swap(tr[x].son[0],tr[x].son[1]);
    }
}
bool isroot(int x)
{
    if(tr[tr[x].fa].son[0]==x||tr[tr[x].fa].son[1]==x) return false;
    return true; 
}
void pushdown(int x)
{
    if(!isroot(x)) pushdown(tr[x].fa);
    update(x);
}
void rotate(int x)
{
    int y=tr[x].fa,z=tr[y].fa,w,R,r;
    w=(tr[y].son[0]==x);

    R=y;r=tr[x].son[w];
    tr[R].son[1-w]=r;
    if(r) tr[r].fa=R;

    R=z;r=x;
    if(!isroot(y)) tr[R].son[tr[z].son[1]==y]=r;
    if(r) tr[r].fa=R;

    R=x;r=y;
    tr[R].son[w]=r;
    if(r) tr[r].fa=R;
    update(y);update(x);
}
void splay(int x)
{
    pushdown(x);
    while(!isroot(x))
    {
        int y=tr[x].fa,z=tr[y].fa;
        if(isroot(y)) rotate(x);
        else
            if((tr[z].son[0]==y)==(tr[y].son[0]==x)) rotate(y),rotate(x);
            else rotate(x),rotate(x);
    }
}
void access(int x)
{
    int last=0;
    while(x)
    {
        splay(x);
        tr[x].son[1]=last;
        update(x);
        last=x;x=tr[x].fa;
    }
}
void make_root(int x)
{
    access(x);
    splay(x);
    tr[x].rev^=1;
}
void split(int x,int y)
{
    make_root(x);
    access(y);
    splay(y);
}
void link(int x,int y)
{
    make_root(x);
    tr[x].fa=y;
}
void cut(int x,int y)
{
    split(x,y);
    tr[x].fa=tr[y].son[0]=0;
    update(y);
}
int find_root(int x)
{
    access(x);
    splay(x);
    while(tr[x].son[0]) x=tr[x].son[0];
    return x;
}
int n,q;
int main()
{
    scanf("%d%d",&n,&q);
    while(q--)
    {
        char str[10];
        int x,y;
        scanf("%s",str);
        scanf("%d %d",&x,&y);
        if(str[0]=='C') link(x,y);
        else if(str[0]=='D') cut(x,y);
        else
        {
            if(find_root(x)==find_root(y)) printf("Yes\n");
            else printf("No\n");
        }
    }
}

你可能感兴趣的:(LCT)