BZOJ 2049 [Sdoi2008]Cave 洞穴勘测 ——Link-Cut Tree

【题目分析】

    LCT另一道题目,很裸,许多操作都不需要,写起来很爽。

【代码】

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
 
#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
#include <queue>
 
using namespace std;
 
#define maxn 1000005
#define inf (0x3f3f3f3f)
 
int read()
{
    int x=0,f=1; char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
 
int fa[maxn],ch[maxn][2],n,m,rev[maxn],sta[maxn],top;
 
bool isroot(int x)
{return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
 
void pushdown (int x)
{
    if (rev[x])
    {
        rev[x]^=1;
        rev[ch[x][0]]^=1;
        rev[ch[x][1]]^=1;
        swap(ch[x][0],ch[x][1]);
    }
}
 
void rot(int x)
{
    int y=fa[x],z=fa[y],l,r;
    if (ch[y][0]==x) l=0; else l=1;
    r=l^1;
    if (!isroot(y))
    {
        if (ch[z][0]==y) ch[z][0]=x;
        else ch[z][1]=x;
    }
    fa[x]=z; fa[y]=x; fa[ch[x][r]]=y;
    ch[y][l]=ch[x][r]; ch[x][r]=y;
}
 
void splay(int x)
{
    top=0; sta[++top]=x;
    for (int i=x;!isroot(i);i=fa[i]) sta[++top]=fa[i];
    while (top) pushdown(sta[top--]);
    while (!isroot(x))
    {
        int y=fa[x],z=fa[y];
        if (!isroot(y))
        {
            if (ch[y][0]==x^ch[z][0]==y) rot(y);
            else rot(x);
        }
        rot(x);
    }
}
 
void access(int x){for (int t=0;x;t=x,x=fa[x]) splay(x),ch[x][1]=t;}
 
void makeroot(int x)
{
    access(x);
    splay(x);
    rev[x]^=1;
}
 
void cut(int x,int y)
{
    makeroot(x);
    access(y);
    splay(y);
    ch[y][0]=fa[x]=0;
}
 
void link(int x,int y)
{
    makeroot(x);
    fa[x]=y;
}
 
int find(int x)
{
    access(x);
    splay(x);
    while (ch[x][0]) x=ch[x][0];
    return x;
}
 
int main()
{
    n=read();m=read();
    while (m--)
    {
        char opt[11];
        int x,y;
        scanf("%s",opt+1); x=read(); y=read();
        if (opt[1]=='Q')
        {
            if (find(x)==find(y)) printf("Yes\n");
            else printf("No\n");
        }
        else if (opt[1]=='C') link(x,y);
        else cut(x,y);
    }
}

  

posted @ 2016-12-18 17:37  SfailSth  阅读(84)  评论(0编辑  收藏  举报