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