LCT

Posted lsq647vsejgfb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LCT相关的知识,希望对你有一定的参考价值。

模板

struct node{
    node *ch[2],*fa;
    int sz;
    bool rev;
    node();
    inline void reverse();
    inline void pushdown();
    inline void pushup();
    inline void contact(node*x);    //很多修改和查询操作会重复使用 
}*null=new node(),tr[N];

node::node(){
    sz=1;
    rev=0;
    ch[0]=ch[1]=fa=null;
}   

inline void node::reverse(){
    swap(ch[0],ch[1]);
    rev^=1;
}

inline void node::pushdown(){
    if(fa->ch[0]==this||fa->ch[1]==this) fa->pushdown();
    if(rev){
        ch[0]->reverse();
        ch[1]->reverse();
        rev=0;
    }
}
    
inline void node::pushup(){
    sz=ch[0]->sz+ch[1]->sz+1;
}

inline void init(){null->ch[0]=null->ch[1]=null->fa=null;null->sz=0;}
//不知道为什么node()无法把null的ch[]和fa初始化为null 

inline void rotate(node*o,int d){
    node*k=o->ch[d^1];
    o->ch[d^1]=k->ch[d];
    k->ch[d]->fa=o;
    k->ch[d]=o;
    if(o->fa->ch[0]==o) o->fa->ch[0]=k;
    else if(o->fa->ch[1]==o) o->fa->ch[1]=k;
    k->fa=o->fa;
    o->fa=k;
    o->pushup();
}

inline void splay(node*x){
    x->pushdown();
    while(x->fa->ch[0]==x||x->fa->ch[1]==x){
        node*y=x->fa,*z=y->fa;
        if(x==y->ch[0]){
            if(y==z->ch[0]) rotate(z,1);
            rotate(y,1);
        }else{
            if(y==z->ch[1]) rotate(z,0);
            rotate(y,0);
        }
    }
    x->pushup();
}

inline void access(node*x){
    node*y=null;
    while(x!=null){
        splay(x);
        x->ch[1]=y;
        x->pushup();
        y=x;
        x=x->fa;
    }
}

inline node* find(node*x){
    access(x);  
    splay(x);
    while(x->ch[0]!=null) x=x->ch[0];
    access(x);
    return x;
}

/*
inline node* find(node*x){      //这样写被卡过一次 
    while(x->fa!=null) x=x->fa;
    return x;
}
*/ 

inline void toroot(node*x){
    access(x);
    splay(x);
    x->reverse();
}

inline void node::contact(node*x){
    toroot(x);
    access(this);
    splay(this);
}

inline void cut(node*x,node*y){
    x->contact(y);
    if(y->fa==x&&y->ch[1]==null){   //判断x和y之间是否有边 
        x->ch[0]=y->fa=null;
        x->pushup();
    }
}

inline void link(node*x,node*y){
    toroot(x);
    x->fa=y;
}

习题

以上是关于LCT的主要内容,如果未能解决你的问题,请参考以下文章

luoguP2173 [ZJOI2012]网络 LCT

一些$LCT$的瓜皮题目

2959: 长跑|LCT+并查集

bzoj 3282 Tree LCT

洛谷P4219 [BJOI2014]大融合(LCT,Splay)

模板多标记 LCT