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!

  • 相关阅读:
    OCP-1Z0-053-200题-125题-155
    OCP-1Z0-053-200题-127题-154答案貌似都不对?
    OCP-1Z0-053-200题-128题-281
    OCP-1Z0-053-200题-129题-153
    OCP-1Z0-053-200题-130题-288
    OCP-1Z0-053-200题-131题-152
    OCP-1Z0-053-200题-132题-272
    OCP-1Z0-053-200题-133题-151
    OCP-1Z0-053-200题-134题-4
    OCP-1Z0-053-200题-135题-150
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/10325245.html
Copyright © 2011-2022 走看看