zoukankan      html  css  js  c++  java
  • UOJ207 共价大爷游长沙

    Link
    我们知道一条边被所有路径经过就是其一个端点的子树中包含了所有路径的一端。
    那么我们可以给每条路径的端点rand一个随机权值,然后用LCT维护子树异或和,查询就是看子树异或和是否等于所有随机权值的异或和。
    LCT维护子树信息+单点修改就是多维护一个虚子树信息,改变虚边的时候修改一下就好了。
    这个方法的正确性还是挺高的,不过我不太会证。

    #include<cstdio>
    #include<cctype>
    #include<cstdlib>
    #include<iostream>
    using std::rand;
    using std::swap;
    namespace IO
    {
        char ibuf[(1<<21)+1],*iS,*iT;
        char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
        int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
    }using namespace IO;
    const int N=100007;
    int ch[N][2],fa[N],rev[N],sum[N],val[N];
    struct node{int u,v,w;}t[N*3];
    #define lc ch[x][0]
    #define rc ch[x][1]
    int nroot(int x){return ch[fa[x]][0]==x||ch[fa[x]][1]==x;}
    void pushup(int x){sum[x]=sum[lc]^sum[rc]^val[x];}
    void pushrev(int x){swap(lc,rc),rev[x]^=1;}
    void pushdown(int x){if(rev[x])pushrev(lc),pushrev(rc),rev[x]=0;}
    void pushall(int x){if(nroot(x))pushall(fa[x]);pushdown(x);}
    void rotate(int x){int y=fa[x],z=fa[y],k=ch[y][1]==x;if(nroot(y))ch[z][ch[z][1]==y]=x;fa[x]=z,fa[y]=x,fa[ch[x][!k]]=y,ch[y][k]=ch[x][!k],ch[x][!k]=y,pushup(y);}
    void splay(int x){pushall(x);for(int y;nroot(x);rotate(x)) if(nroot(y=fa[x])) rotate((ch[fa[y]][0]==y)^(ch[y][0]==x)? y:x);pushup(x);}
    void access(int x){for(int y=0;x;x=fa[y=x])splay(x),val[x]^=sum[y]^sum[rc],rc=y,pushup(x);}
    void makeroot(int x){access(x),splay(x),pushrev(x);}
    void link(int x,int y){makeroot(x),makeroot(y),val[y]^=sum[x],fa[x]=y;}
    void cut(int x,int y){makeroot(y),access(y),splay(x),fa[x]=0,val[y]^=sum[x];}
    void update(int x,int w){access(x),splay(x),val[x]^=w;}
    #undef lc
    #undef rc
    int main()
    {
        srand(19260817),read();int n=read(),m=read(),s=0,c=0;
        for(int i=1;i<n;++i) link(read(),read());
        for(int u,v,w;m;--m)
    	switch(read())
    	{
    	case 1:cut(read(),read()),link(read(),read());break;
    	case 2:u=read(),v=read(),w=rand()*32768+rand(),update(u,w),update(v,w),s^=w,t[++c]={u,v,w};break;
    	case 3:u=read(),update(t[u].u,t[u].w),update(t[u].v,t[u].w),s^=t[u].w;break;
    	case 4:u=read(),v=read(),makeroot(u),access(v),puts(val[v]==s?"YES":"NO");break;
    	}
    }
    
  • 相关阅读:
    ios10兼容问题
    safari图片跨域
    出现Unable to locate appropriate constructor on class 错误可能的原因
    localStorage、sessionStorage用法以及区别
    多行文本垂直居中,多行文本溢出
    【汉字】转【pīnyīn】
    移除行块级元素之间的空格(译文)
    jquery插件——检测DOM元素是否在浏览器可视范围之内
    监控阮一峰老师的blog
    PHP实现linux命令tail -f
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12219157.html
Copyright © 2011-2022 走看看