zoukankan      html  css  js  c++  java
  • [模板]Link Cut Tree

    传送门

    Description

    给定n个点以及每个点的权值,要你处理接下来的m个操作。操作有4种。操作从0到3编号。点从1到n编号。

    0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。

    1:后接两个整数(x,y),代表连接x到y,若x到y已经联通则无需连接。

    2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。

    3:后接两个整数(x,y),代表将点x上的权值变成y。

    Solution

    (Link Cut Tree)模板题

    (findroot)后要(Splay)到根?不然复杂度不保证???

    在洛谷上实测(535ms),还算比较快吧

    函数变量名奇异+神仙缩行( ightarrow) 还是别看了


    Code 

    //2019.1.26 18:41-22:54
    #include<bits/stdc++.h>
    inline int read()
    {
    	register int x=0,f=1;register char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	return x*f;
    }
    class Link_Cut_Tree
    {
    	#define MN 300005 
    	private:
    		int N,fa[MN],c[MN][2],st[MN],val[MN],X[MN];
    		bool rev[MN];
    		inline bool nrt(int x){return c[fa[x]][0]==x||c[fa[x]][1]==x;}
    		inline void Rev(int x){rev[x]^=1;std::swap(c[x][0],c[x][1]);}
    		inline void up(int x){X[x]=X[c[x][0]]^X[c[x][1]]^val[x];}
    		inline void down(int x){if(x&&rev[x])Rev(c[x][0]),Rev(c[x][1]),rev[x]=0;}
    		#define get(x) (c[fa[x]][1]==x)
    		inline void rotate(int x)
    		{
    			int y=fa[x],z=fa[y],l=get(x),r=l^1;if(nrt(y))c[z][get(y)]=x;fa[x]=z;
    			c[y][l]=c[x][r];fa[c[x][r]]=y;c[x][r]=y;fa[y]=x;up(y);
    		}
    		inline void Splay(int x)
    		{
    			static int top,q[MN];q[top=1]=x;register int i;
    			for(i=x;nrt(i);i=fa[i]) q[++top]=fa[i];for(;top;--top) down(q[top]);
    			for(;nrt(x);rotate(x))if(nrt(fa[x])) rotate(get(fa[x])^get(x)?x:fa[x]);up(x);
    		}
    		#undef get
    		inline void access(int x){register int i;for(i=0;x;x=fa[i=x])Splay(x),c[x][1]=i,up(x);}
    		inline void mkrt(int x){access(x);Splay(x);Rev(x);}
    		inline int fdrt(int x){access(x),Splay(x);for(;c[x][0];down(c[x][0]),x=c[x][0]);Splay(x);return x;}
    		inline void Split(int x,int y){mkrt(x);access(y);Splay(y);}
    	public:
    		inline void init(int n){register int i;for(i=1;i<=n;++i) val[i]=X[i]=read();}
    		void Link(int x,int y){mkrt(x);if(fdrt(y)!=x)fa[x]=y;}
    		void Cut(int x,int y){Split(x,y);if(c[y][0]==x&&!c[x][1])c[y][0]=fa[x]=0,up(y);}
    		inline int Query(int x,int y){if(x==y) return val[x];Split(x,y);return X[y];}
    		inline void Modify(int x,int V){Splay(x);val[x]=V;up(x);}
    	#undef MN
    }T;
    int main()
    {
    	register int n=read(),m=read(),opt,x;T.init(n);
    	while(m--)
    	{
    		opt=read(),x=read();
    		switch(opt)
    		{
    			case 0:printf("%d
    ",T.Query(x,read()));break;
    			case 1:T.Link(x,read());break;
    			case 2:T.Cut(x,read());break;
    			case 3:T.Modify(x,read());break;
    		}
    	}
    }
    
    


    Blog来自PaperCloud,未经允许,请勿转载,TKS!

  • 相关阅读:
    Constants and Variables
    随想
    C#基础篇之语言和框架介绍
    Python基础19 实例方法 类方法 静态方法 私有变量 私有方法 属性
    Python基础18 实例变量 类变量 构造方法
    Python基础17 嵌套函数 函数类型和Lambda表达式 三大基础函数 filter() map() reduce()
    Python基础16 函数返回值 作用区域 生成器
    Python基础11 List插入,删除,替换和其他常用方法 insert() remove() pop() reverse() copy() clear() index() count()
    Python基础15 函数的定义 使用关键字参数调用 参数默认值 可变参数
    Python基础14 字典的创建修改访问和遍历 popitem() keys() values() items()
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/10325245.html
Copyright © 2011-2022 走看看