zoukankan      html  css  js  c++  java
  • 洛谷P3690 【模板】Link Cut Tree (动态树)

    题目

    https://www.luogu.com.cn/problem/P3690

    仅仅是存个代码而已,以备复习。。。

    代码

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #define maxn (int)(1e5+10)
    using namespace std;
    int val[maxn];
    struct LCT{
    	struct node{
    		int father,lson,rson,path_parent;
    		int sum,tag,size;
    	} tree[maxn];
    	int cnt;
    	private:
    		void update(int x){
    			tree[x].sum=tree[tree[x].lson].sum^tree[tree[x].rson].sum^val[x];
    			tree[x].size=tree[tree[x].lson].size+tree[tree[x].rson].size+1;
    		}
    		void pushdown(int x){
    			if(tree[x].tag){
    				tree[x].tag=0;
    				if(tree[x].lson) tree[tree[x].lson].tag^=1;
    				if(tree[x].rson) tree[tree[x].rson].tag^=1;
    				swap(tree[x].lson,tree[x].rson);
    			}
    		}
    		void zig(int x){
    			int y=tree[x].father;
    			tree[x].father=tree[y].father;
    			tree[x].path_parent=tree[y].path_parent;
    			tree[y].path_parent=0;
    			if(tree[y].father)
    				if(tree[tree[y].father].lson==y) tree[tree[y].father].lson=x;
    				else tree[tree[y].father].rson=x;
    			int z=tree[x].rson;
    			if(z) tree[z].father=y;
    			tree[y].lson=z;
    			tree[x].rson=y;
    			tree[y].father=x;
    			update(y);update(x);
    		}
    		void zag(int x){
    			int y=tree[x].father;
    			tree[x].father=tree[y].father;
    			tree[x].path_parent=tree[y].path_parent;
    			tree[y].path_parent=0;
    			if(tree[y].father)
    				if(tree[tree[y].father].lson==y) tree[tree[y].father].lson=x;
    				else tree[tree[y].father].rson=x;
    			int z=tree[x].lson;
    			if(z) tree[z].father=y;
    			tree[y].rson=z;
    			tree[x].lson=y;
    			tree[y].father=x;
    			update(y);update(x);
    		}
    		void splay(int x){
                pushdown_all(x);
    			while(tree[x].father){
    				int y=tree[x].father,z=tree[y].father;
    				if(!z){
    					if(tree[y].lson==x) zig(x);
    					else zag(x);
    				}
    				else{
    					if(tree[y].lson==x&&tree[z].lson==y){
    						zig(y);zig(x);
    					}
    					else if(tree[y].rson==x&&tree[z].rson==y){
    						zag(y);zag(x);
    					}
    					else if(tree[y].lson==x&&tree[z].rson==y){
    						zig(x);zag(x);
    					}
    					else{
    						zag(x);zig(x);
    					}
    				}
    			}
    		}
    		void pushdown_all(int x){
    			if(tree[x].father) pushdown_all(tree[x].father);
    			pushdown(x);
    			return;
    		}
    		void access(int x){
    			splay(x);
    			if(tree[x].rson){
    				tree[tree[x].rson].path_parent=x;
    				tree[tree[x].rson].father=0;
    				tree[x].rson=0;
    				update(x);
    			}
    			while(tree[x].path_parent){
    				int u=tree[x].path_parent;
    				splay(u);
    				if(tree[u].rson){
    					tree[tree[u].rson].path_parent=u;
    					tree[tree[u].rson].father=0;
    					update(u);
    				}
    				tree[u].rson=x;
    				tree[x].father=u;
    				tree[x].path_parent=0;
    				update(u);
    				x=u;
    			}
    			splay(x);
    		}
    		void evert(int x){
    			access(x);splay(x);
    			tree[x].tag^=1;
    			pushdown(x);
    		}
    		int find_root(int x){
    			access(x);splay(x);
    			int t=x;
    			while(1){
                    pushdown(t);
                    if(!tree[t].lson) break;
    				t=tree[t].lson;
    			}
    			return t;
    		}
    	public:
    		void link(int x,int y){
    			evert(x);
    			if(find_root(y)==x) return;
    			access(y);splay(y);
    			tree[y].father=x;
    			tree[x].lson=y;
    			update(x);
    		}
    		void cut(int x,int y){
    			evert(x);
    			if(find_root(y)!=x) return;
    			access(y);splay(y);
                if(tree[y].size>2) return;
    			tree[x].father=0;
    			tree[y].lson=0;
    			update(y);
    		}
    		int get_sum(int x,int y){
    			evert(x);
    			access(y);splay(y);
    			return tree[y].sum;
    		}
    		void modify(int x,int y){
    			val[x]=y;
    			splay(x);
    			update(x);
    		}
    		void insert(int x){
    			tree[x].father=tree[x].lson=tree[x].rson=0;
    			tree[x].path_parent=0;
    			tree[x].size=1;
    			tree[x].tag=0;
    			tree[x].sum=val[x];
    		}
    } T;
    int main(){
    	int i,j,n,m;
    	int op,x,y;
        // freopen("T.in","r",stdin);
        // freopen("myans.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for(i=1;i<=n;i++)
    		scanf("%d",&val[i]);
    	for(i=1;i<=n;i++)
    		T.insert(i);
    	for(i=1;i<=m;i++){
    		scanf("%d%d%d",&op,&x,&y);
    		if(op==0) printf("%d
    ",T.get_sum(x,y));
    		if(op==1) T.link(x,y);
    		if(op==2) T.cut(x,y);
    		if(op==3) T.modify(x,y);
    	}
        // system("pause");
    	return 0;
    }
  • 相关阅读:
    Android实现简单的检测手机自由落体关闭屏幕
    Android Disable Package/Component 跳过app安装
    求单向链表中倒数第k个节点(c++):快慢指针/递归
    算法学习笔记---链表与数组
    pycharm使用matplotlib绘图学习笔记
    pycharm使用matplotlib绘制图像报错
    python numpy学习笔记
    python刷leetcode算法-- 左旋转字符串
    机器学习算法扫盲篇
    Kaggle入门篇
  • 原文地址:https://www.cnblogs.com/landmine-sweeper/p/14629225.html
Copyright © 2011-2022 走看看