BZOJ2049: [Sdoi2008]Cave 洞穴勘测

【传送门:BZOJ2049


简要题意:

  给出n个点,有m种操作:

  1.Connect x y将x点和y点连通

  2.Destroy x y使得x点和y点不连通

  3.Query x y询问x和y是否连通


题解:

  LCT的模板题,动态树例题

  LCT浅谈 by师兄


参考代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
struct node
{
    int f,son[2];
    bool fz;
    node()
    {
        fz=false;
    }
}tr[110000];
void reverse(int x)
{
    tr[x].fz=false;
    swap(tr[x].son[0],tr[x].son[1]);
    int lc=tr[x].son[0],rc=tr[x].son[1];
    tr[lc].fz=1-tr[lc].fz;
    tr[rc].fz=1-tr[rc].fz;
}
void rotate(int x,int w)
{
    int f=tr[x].f,ff=tr[f].f;
    int r,R;
    r=tr[x].son[w],R=f;
    tr[R].son[1-w]=r;
    if(r!=0) tr[r].f=R;
    r=x;R=ff;
    if(tr[R].son[0]==f) tr[R].son[0]=r;
    else if(tr[R].son[1]==f) tr[R].son[1]=r;
    tr[r].f=R;
    r=f;R=x;
    tr[R].son[w]=r;
    tr[r].f=R;
}
int tmp[11000];
void splay(int x,int rt)
{
    int i=x;int s=0;
    while(tr[i].f!=0&&(tr[tr[i].f].son[0]==i||tr[tr[i].f].son[1]==i))
    {
        tmp[++s]=i;
        i=tr[i].f;
    }
    tmp[++s]=i;
    while(s!=0)
    {
        i=tmp[s--];
        if(tr[i].fz==true) reverse(i);
    }
    while(tr[x].f!=0&&(tr[tr[x].f].son[0]==x||tr[tr[x].f].son[1]==x))
    {
        int f=tr[x].f,ff=tr[f].f;
        if(ff==rt||(tr[ff].son[0]!=f&&tr[ff].son[1]!=f))
        {
            if(tr[f].son[0]==x) rotate(x,1);
            else if(tr[f].son[1]==x) rotate(x,0);
        }
        else
        {
            if(tr[f].son[0]==x&&tr[ff].son[0]==f){rotate(f,1);rotate(x,1);continue;}
            if(tr[f].son[0]==x&&tr[ff].son[1]==f){rotate(x,1);rotate(x,0);continue;}
            if(tr[f].son[1]==x&&tr[ff].son[0]==f){rotate(x,0);rotate(x,1);continue;}
            if(tr[f].son[1]==x&&tr[ff].son[1]==f){rotate(f,0);rotate(x,0);continue;}
        }
    }
}
void access(int x)
{
    int y=0;
    while(x!=0)
    {
        splay(x,0);
        tr[x].son[1]=y;
        if(y!=0) tr[y].f=x;
        y=x;x=tr[x].f;
    }
}
void makeroot(int x)
{
    access(x);splay(x,0);
    tr[x].fz=1-tr[x].fz;
}
void link(int x,int y)
{
    makeroot(x);
    tr[x].f=y;
    access(x);
}
void cut(int x,int y)
{
    makeroot(x);
    access(y);
    splay(y,0);
    tr[tr[y].son[0]].f=0;tr[y].son[0]=0;
}
int findroot(int x)
{
    access(x);
    splay(x,0);
    while(tr[x].son[0]!=0) x=tr[x].son[0];
    return x;
}
char st[11];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%s%d%d",st+1,&x,&y);
        if(st[1]=='Q') if(findroot(x)==findroot(y)) printf("Yes\n");else printf("No\n");
        if(st[1]=='C') link(x,y);
        if(st[1]=='D') cut(x,y);
    }
    return 0;
}

 

posted @ 2018-03-23 09:41  Star_Feel  阅读(152)  评论(0编辑  收藏  举报