BZOJ 2049: [Sdoi2008]Cave 洞穴勘测——LCT

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2049

省选之前来切一道数据结构模板题。

题意

这是一道模板题

N个点,M次操作,每次加边/删边/询问两个点是否连通,保证每次操作之后仍然是一棵树。

N<=1e4,M<=2e5。

做法

裸的LCT。

需要支持查找一个点所在树的根,只要不断向上查找father就行了。

(fread就是快啊。

#include <bits/stdc++.h>
using namespace std;
const int MAXN=20005, MAXB=2e7;
char BUF[MAXB], *cp=BUF;
void rd(int &x){
    x=0;
    while(*cp<'0'||'9'<*cp) cp++;
    while('0'<=*cp&&*cp<='9') x=x*10+*cp-'0', cp++;
}
char rdc(){
    while(*cp<'A'||'Z'<*cp) cp++;
    return *cp;
}

int N, M, top;

struct Node{
    Node *ch[2], *fa;
    int re;
}nd[MAXN], *rt, *st[MAXN];

inline int isrt(Node *x){return !(x->fa->ch[0]==x||x->fa->ch[1]==x);}

void rot(Node *x){
    Node *y=x->fa, *z=y->fa;
    int l=y->ch[1]==x, r=!l;
    if(!isrt(y)) z->ch[z->ch[1]==y]=x;
    x->ch[r]->fa=y; y->fa=x; x->fa=z;
    y->ch[l]=x->ch[r]; x->ch[r]=y;
}

void down(Node *x){
    if(x->re){
        x->ch[0]->re^=1; x->ch[1]->re^=1;
        swap(x->ch[0], x->ch[1]); x->re=0;
    }
}

void splay(Node *x){
    st[top++]=x;
    for(Node *i=x; !isrt(i); i=i->fa) st[top++]=i->fa;
    for(;top;--top) down(st[top-1]);
    while(!isrt(x)){
        Node *y=x->fa, *z=y->fa;
        if(!isrt(y)) rot((z->ch[1]==y)^(y->ch[1]==x)?x:y);
        rot(x);
    }
}

inline void access(Node *x){
    for(Node *i=nd; x!=nd; i=x,x=x->fa)
        splay(x), x->ch[1]=i;
}

inline void mkrt(Node *x){access(x),splay(x),x->re^=1;}

inline Node *getrt(Node *x){while(x->fa!=nd)x=x->fa; return x;}

inline void lin(Node *x, Node *y){mkrt(x); x->fa=y;}

inline void cut(Node *x, Node *y){
    mkrt(x); access(y); splay(y);
    y->ch[0]=x->fa=nd;
}

int main(){
    fread(BUF, 1, MAXB, stdin);
    rd(N),rd(M);
    for(int i=0; i<=N; ++i) nd[i].ch[0]=nd[i].ch[1]=nd[i].fa=nd;
    for(int i=0,u,v; i<M; ++i){
        char ch=rdc(); rd(u), rd(v);
        if(ch=='Q') puts(getrt(nd+u)==getrt(nd+v)?"Yes":"No");
        else if(ch=='C') lin(nd+u,nd+v);
        else cut(nd+u,nd+v);
    }
    return 0;
}
posted @ 2017-04-06 20:17 will7101 阅读(...) 评论(...) 编辑 收藏