LCT模板

Posted lsq647vsejgfb

tags:

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

1


struct nd{
    nd *ch[2],*fa;
    int s,v;
    bool r,isr();
    nd();
    iv rev(),pd(),pu(),cta(nd*x),rot(int d);    //很多修改和查询操作会重复使用 
}*nul=new nd(),t[N];

bool nd::isr(){
    return fa->ch[0]!=this&&fa->ch[1]!=this;
}

nd::nd(){
    s=r=v=0;
    ch[0]=ch[1]=fa=nul;
}   

iv nd::rev(){
    swap(ch[0],ch[1]);
    r^=1;
}

iv nd::pd(){
    if(!isr()) fa->pd();
    if(r){
        ch[0]->rev();
        ch[1]->rev();
        r=0;
    }
}
iv nd:: pu(){
    s=ch[0]->s^ch[1]->s^v;
}

iv init(){nul->ch[0]=nul->ch[1]=nul->fa=nul;nul->s=0;}
//不知道为什么nd()无法把nul的ch[]和fa初始化为nul 


iv nd::rot(int d){
    nd*k=ch[d^1];
    ch[d^1]=k->ch[d],k->ch[d]->fa=this;
    k->ch[d]=this;
    if(!isr()) fa->ch[fa->ch[1]==this]=k;
    k->fa=fa,fa=k,pu();
}

iv splay(nd*x){
    x->pd();
    while(!x->isr()){
        nd*y=x->fa,*z=y->fa;
        if(x==y->ch[0]){
            if(y==z->ch[0]) z->rot(1);
            y->rot(1);
        }else{
            if(y==z->ch[1]) z->rot(0);
            y->rot(0);
        }
    }
    x->pu();
}

iv acc(nd*x){
    nd*y=nul;
    while(x!=nul){
        splay(x);
        x->ch[1]=y;
        x->pu();
        y=x;
        x=x->fa;
    }
}

inline nd* find(nd*x){
    acc(x);  
    splay(x);
    while(x->ch[0]!=nul) x=x->ch[0];
    acc(x);
    return x;
}

iv tor(nd*x){
    acc(x);
    splay(x);
    x->rev();
}

iv nd::cta(nd*x){
    tor(x);
    acc(this);
    splay(this);
}

iv cut(nd*x,nd*y){
    x->cta(y);
    if(y->fa==x&&y->ch[1]==nul){   //判断x和y之间是否有边 
        x->ch[0]=y->fa=nul;
        x->pu();
    }
}

iv link(nd*x,nd*y){
    tor(x);
    x->fa=y;
}


2

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模板的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ2049,2631,3282,1180LCT模板四连A

模板LCT

模板LCT

LCT模板

lct模板

LCT模板