zoukankan      html  css  js  c++  java
  • UOJ#207. 共价大爷游长沙 LCT

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ207.html

    题解

      第一次听说 LCT 还可以维护子树信息。

      首先对于每一条路径 rand 一个值,分别放在两个端点上,于是询问一条边是否被所有路径的经过就变成了询问某一边所代表的子树是否包含所有路径的端点各一次。于是我求出子树 xor ,并与当前所有路径值的 xor 比较是否相同就可以判断了。

      于是接下来就变成了 LCT 维护子树 xor 。

      考虑在 LCT 的时候,再对于每一个节点维护其虚儿子的信息。由于 LCT 涉及虚儿子的操作十分少,所以只需要在修改边的虚实关系的时候顺便维护一下就好了。

      时间复杂度 $O((n+m)log n)$ 。

    代码

    #include <bits/stdc++.h>
    #define link __zzd001
    using namespace std;
    typedef long long LL;
    int read(){
        int x=0;
        char ch=getchar();
        while (!isdigit(ch))
            ch=getchar();
        while (isdigit(ch))
            x=(x<<1)+(x<<3)+ch-48,ch=getchar();
        return x;
    }
    const int N=100005;
    int n,m,id;
    int fa[N],son[N][2],rev[N],val[N],sum[N];
    void pushup(int x){
    	sum[x]=sum[son[x][0]]^val[x]^sum[son[x][1]];
    }
    int isroot(int x){
    	return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;
    }
    int wson(int x){
    	return son[fa[x]][1]==x;
    }
    void rotate(int x){
    	if (isroot(x))
    		return;
    	int y=fa[x],z=fa[y],L=wson(x),R=L^1;
    	if (!isroot(y))
    		son[z][wson(y)]=x;
    	fa[x]=z,fa[y]=x,fa[son[x][R]]=y;
    	son[y][L]=son[x][R],son[x][R]=y;
    	pushup(y),pushup(x);
    }
    void pushdown(int x){
    	if (rev[x]){
    		swap(son[x][0],son[x][1]);
    		rev[son[x][0]]^=1;
    		rev[son[x][1]]^=1;
    		rev[x]=0;
    	}
    }
    void pushadd(int x){
    	if (!isroot(x))
    		pushadd(fa[x]);
    	pushdown(x);
    }
    void splay(int x){
    	pushadd(x);
    	for (int y=fa[x];!isroot(x);rotate(x),y=fa[x])
    		if (!isroot(y))
    			rotate(wson(x)==wson(y)?y:x);
    }
    void access(int x){
    	for (int t=0;x;t=x,x=fa[x]){
    		splay(x);
    		val[x]^=sum[son[x][1]]^sum[t];
    		fa[t]=x,son[x][1]=t;
    		pushup(x);
    	}
    }
    void rever(int x){
    	access(x),splay(x),rev[x]^=1;
    }
    void link(int x,int y){
    	rever(x),rever(y);
    	fa[x]=y,val[y]^=sum[x];
    	pushup(y);
    }
    void cut(int x,int y){
    	rever(x),access(y),splay(y);
    	son[y][0]=fa[x]=0;
    	pushup(y);
    }
    int randv[N*3],rands=0,cnt=0;
    pair <int,int> path[N*3];
    int randint(){
    	int a=rand()&65535,b=rand()&65535;
    	return (a<<15)^b;
    }
    int main(){
    	srand('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I');
    	id=read(),n=read(),m=read();
    	for (int i=1;i<n;i++){
    		int x=read(),y=read();
    		link(x,y);
    	}
    	while (m--){
    		int opt=read(),x,y,u,v;
    		if (opt==1){
    			x=read(),y=read(),u=read(),v=read();
    			cut(x,y),link(u,v);
    		}
    		else if (opt==2){
    			x=read(),y=read();
    			int now=randv[++cnt]=randint();
    			path[cnt]=make_pair(x,y);
    			rever(x),val[x]^=now,pushup(x);
    			rever(y),val[y]^=now,pushup(y);
    			rands^=now;
    		}
    		else if (opt==3){
    			u=read();
    			int now=randv[u];
    			x=path[u].first,y=path[u].second;
    			rever(x),val[x]^=now,pushup(x);
    			rever(y),val[y]^=now,pushup(y);
    			rands^=now;
    		}
    		else if (opt==4){
    			x=read(),y=read();
    			rever(x);
    			access(y);
    			splay(y);
    			puts(rands==sum[x]?"YES":"NO");
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    第三天 moyax
    mkfs.ext3 option
    write file to stroage trigger kernel warning
    download fomat install rootfs script
    custom usb-seriel udev relus for compatible usb-seriel devices using kermit
    Wifi Troughput Test using iperf
    learning uboot switch to standby system using button
    learning uboot support web http function in qca4531 cpu
    learngin uboot design parameter recovery mechanism
    learning uboot auto switch to stanbdy system in qca4531 cpu
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/UOJ207.html
Copyright © 2011-2022 走看看