• 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;
    }
    
  • 相关阅读:
    [Leetcode] Copy List with Random Pointer
    [Java] StringBuffer类
    [Leetcode] Wildcard Matching
    [Leetcode] Substring with Concatenation of All Words
    [Leetcode] Longest Palindromic Substring
    [Leetcode] Maximum Product Subarray
    [leetcode] Permutation Sequence
    [Leetcode] Simplify Path
    [Leetcode] Minimum Window Substring
    Owin asp.net 脱离 IIS
  • 原文地址:https://www.cnblogs.com/lsq647vsejgfb/p/9496648.html
Copyright © 2020-2023  润新知