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