2049: [Sdoi2008]Cave 洞穴勘测 LCT第一题

话说都高一了,我居然还不会LCT
于是今天,终于写了第一发LCT,虽然是最简单的,很多操作都没有。。
但总归是我写的第一发。。
话说我在写的是否发现一个很需要注意的地方,就是要注意rotate的时候要判一下不能是根,要不会GG
在bzoj居然是MLE,真奇怪,难道是入栈太多了?

#include
#include
#include
#include
#include
using namespace std;
const int N=30005;
struct node
{
    int son[2],fa;
    bool rev;
}s[N];
int n,m;
bool Is_root(int x)
{
  if((s[s[x].fa].son[0]!=x)&&(s[s[x].fa].son[1]!=x)) return true;
  return false;
}
void rotate (int x)
{
    int y=s[x].fa,z=s[y].fa;
    int r,R,f,w;
    if (s[y].son[0]==x) w=1;
    else w=0;

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

    r=x;R=z;
    if (!Is_root(y))
    {
        if (s[R].son[0]==y) s[R].son[0]=r;
        else s[R].son[1]=r;
    }
    if (r!=0) s[r].fa=R;

    r=y;R=x;
    s[R].son[w]=r;
    if (r!=0) s[r].fa=R;
}
void Push_down (int x)
{
      if(s[x].rev)
      {
        s[s[x].son[1]].rev^=1; s[s[x].son[0]].rev^=1;
        swap(s[x].son[0],s[x].son[1]);
        s[x].rev=0;
      }
}
stack<int> S;
void Preserve (int x)
{
    while (!Is_root(x)) S.push(x),x=s[x].fa;S.push(x);
    while (!S.empty()) Push_down(S.top()),S.pop();
}
void Splay (int x)
{
    Preserve(x);
    while (!Is_root(x))
    {
        //printf("%d %d %d\n",x,s[x].fa,s[0].son[0]);
        int y=s[x].fa,z=s[y].fa;
        if (!Is_root(y))
        {
            if ((s[y].son[1]==x)==(s[z].son[1]==y)) rotate(y);
            else rotate(x);
        }
        rotate(x);
    }
}
void Access (int x)
{
    int last=0;
    while (x!=0)
    {
        Splay(x);
        s[x].son[1]=last;
        last=x;
        x=s[x].fa;
    }
}
void Make_root (int x)
{
    Access(x);
    Splay(x);
    s[x].rev^=1;
}
void Link (int x,int y)
{
    Make_root(y);
    s[y].fa=x;
}
void Split (int x,int y)
{
    Make_root(x);
    Access(y);
    Splay(y);
}
void Cut (int x,int y)
{
    Split(x,y);
    s[x].fa=0;
    s[y].son[0]=0;
}
int Find_root(int x)
{
    Access(x);
//  printf("YES\n");
    Splay(x);
//  printf("NO\n");
    while (s[x].son[0]!=0) 
    {
        x=s[x].son[0];

    }
    return x;
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int u=1;u<=n;u++) s[u].son[0]=s[u].son[1]=0,s[u].fa=0;
    while (m--)
    {
        char ss[15];
        int x,y;
        scanf("%s%d%d",ss,&x,&y);
        if (ss[0]=='C')//建边
            Link(x,y); 
        else if (ss[0]=='D')
            Cut(x,y);
        else
        {
            if (Find_root(x)==Find_root(y)) printf("Yes\n");
            else printf("No\n");
        }
    }
    return 0;
}

你可能感兴趣的:(LCT)