zoukankan      html  css  js  c++  java
  • 【BZOJ 3282】Tree Link Cut Tree模板题

    知道了为什么要换根(changeroot),access后为什么有时要splay,以及LCT的其他操作,算是比较全面的啦吧,,,

    现在才知道这些,,,真心弱,,,

    #include<cstdio>
    #include<algorithm>
    #define read(x) x=getint()
    using namespace std;
    const int N=300003;
    inline int getint(){char c;int ret=0;for(c=getchar();c<'0'||c>'9';c=getchar());for(;c>='0'&&c<='9';c=getchar())ret=ret*10+c-'0';return ret;}
    struct node *null;
    struct node{
    	node();
    	node *fa,*ch[2];
    	int d,rev,w;
    	void push() {if(rev) {ch[0]->rev^=1; ch[1]->rev^=1; rev=0; swap(ch[0],ch[1]);}}
    	void count() {w=ch[0]->w^ch[1]->w^d;}
    	void setc(node *r,bool c) {ch[c]=r; r->fa=this;}
    	bool check() {return fa==null||((fa->ch[0]!=this)&&(fa->ch[1]!=this));}
    	bool pl() {return fa->ch[1]==this;}
    }*T[N];
    node::node() {d=rev=w=0; fa=ch[0]=ch[1]=null;}
    int n;
    inline void Build() {null=new node; *null=node();}
    inline void rotate(node *r){
    	node *f=r->fa;
    	bool c=r->pl();
    	if (!f->check()) f->fa->setc(r,f->pl());
    	else r->fa=f->fa;
    	f->setc(r->ch[!c],c); r->setc(f,!c);
    	f->count();
    }
    inline void update(node *r) {if (!r->check()) update(r->fa); r->push();}
    inline void splay(node *r){
    	update(r);
    	for(;!r->check();rotate(r))
    		if (!r->fa->check()) rotate(r->fa->pl()==r->pl()?r->fa:r);
    	r->count();
    }
    inline node *access(node *r){
    	node *y=null;
    	for(;r!=null;y=r,r=r->fa){
    		splay(r);
    		r->setc(y,1);
    		r->count();
    	}
    	return y;
    }
    inline void changeroot(node *r) {access(r)->rev^=1; splay(r);}
    inline void cut(node *r,node *y) {changeroot(r); access(y); splay(y); y->ch[0]->fa=null; y->ch[0]=null;}
    inline void link(node *r,node *y) {changeroot(r); r->fa=y;}
    inline node *findroot(node *r) {access(r); splay(r); while(r->ch[0]!=null) r=r->ch[0]; return r;}
    int main(){
    	Build();
    	read(n); int x,q,a,b; read(q);
    	for(int i=1;i<=n;i++) {T[i]=new node; read(T[i]->d); T[i]->w=T[i]->d;}
    	while (q--){
    		read(x); read(a); read(b);
    		switch (x){
    			case 0:
    				changeroot(T[a]); access(T[b]); splay(T[b]); printf("%d
    ",T[b]->w);
    			break;
    			case 1:
    				if (findroot(T[a])!=findroot(T[b])) link(T[a],T[b]);
    			break;
    			case 2:
    				if (findroot(T[a])==findroot(T[b])) cut(T[a],T[b]);
    			break;
    			case 3:
    				changeroot(T[a]); T[a]->d=b; T[a]->count();
    			break;
    		}
    	}
    	return 0;
    }
    

    这样就行啦

  • 相关阅读:
    滚动相册
    智能拼图
    连连看
    魔法色块
    ASP.NET Session的七点认识
    从11月开始windows update速度缓慢,中国反击?
    WM实现文件关联
    与黄河老师合影
    ubuntu8.04笔记本开启无线网卡记得开网卡的电源
    无法在Web服务器上启动调试,与Web服务器通信时出现身份验证错误
  • 原文地址:https://www.cnblogs.com/abclzr/p/5267290.html
Copyright © 2011-2022 走看看