BZOJ2049 SDOI2008 洞穴勘测 LCT

题意:给定一棵树,维护:1、删除一条边  2、添加一条边  3、询问u和v是否连通

题解:LCT维护连通性

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN=10000+2;
typedef struct NODE{
    NODE *child[2],*f;
    bool rev;
} *TREE;
TREE root,Null,mark[MAXN];
int N,M;
char s[10];

TREE NewNode(TREE f){
    TREE x=new NODE;
    x->f=f,x->child[0]=x->child[1]=Null;
    x->rev=0;
    return x;
}

void Initialize(int N){
    Null=NewNode(0);
    for(int i=1;i<=N;i++) mark[i]=NewNode(Null);
}

void Pushdown(TREE &x){
    if(x->f->child[0]==x || x->f->child[1]==x) Pushdown(x->f);
    if(x->rev){
        swap(x->child[0],x->child[1]);
        x->child[0]->rev^=1,x->child[1]->rev^=1;
        x->rev=0;
    }
}

void Rotate(TREE &x,bool t){
    TREE y=x->f;
    y->child[!t]=x->child[t],x->child[t]->f=y,x->f=y->f;
    if(y->f->child[0]==y) y->f->child[0]=x;
    if(y->f->child[1]==y) y->f->child[1]=x;
    x->child[t]=y,y->f=x;
}

void Splay(TREE &x){
    Pushdown(x);

    TREE y=x->f;
    while(y->child[0]==x || y->child[1]==x){
        if(y->child[0]==x){
            if(y->f->child[0]==y) Rotate(y,1);
            Rotate(x,1);
        }
        else{
            if(y->f->child[1]==y) Rotate(y,0);
            Rotate(x,0);
        }
        y=x->f;
    }
}

void Access(TREE &x){
    TREE y=Null,z=x;
    while(z!=Null){
        Splay(z);
        z->child[1]=y;
        y=z,z=z->f;
    }
}

void Move(TREE &x){
    Access(x),Splay(x);
    x->rev^=1,Pushdown(x);
}

void Link(TREE &x,TREE &y){
    Move(x);
    x->child[0]=Null,x->f=y;
}

void Cut(TREE &x,TREE &y){
    Move(x);
    x->child[1]=Null;
    Access(y);
    x->child[1]=Null;
    Splay(y);
    y->f=Null;
}

TREE Query(TREE &x){
    TREE y=x;
    while(y->f!=Null) y=y->f;
    return y;
}

int main(){
    scanf("%d %d",&N,&M);
    Initialize(N);
    for(int i=1,x,y;i<=M;i++){
        scanf("%s %d %d",s,&x,&y);
        if(s[0]=='Q')
            if(Query(mark[x])==Query(mark[y])) puts("Yes");
            else puts("No");
        if(s[0]=='C') Link(mark[x],mark[y]);
        if(s[0]=='D') Cut(mark[x],mark[y]);
    }

    return 0;
}
View Code

 

posted @ 2017-02-26 13:56  WDZRMPCBIT  阅读(139)  评论(0编辑  收藏  举报