• luogu P3690 【模板】Link Cut Tree (动态树)


    https://www.luogu.org/problemnew/show/3690

    这大概还是一道模板题目

    #include<cstdio>
    #include<algorithm>
    const int maxn = 320007;
    inline int read() {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9') {
            if(c=='-')f=-1;c=getchar();
        }
        while(c<='9'&&c>='0') {
            x=x*10+c-'0',c=getchar();
        }
        return x*f;
    }
    #define lc ch[x][0]
    #define rc ch[x][1]
    bool rev[maxn];
    int stack[maxn],top;
    int ans[maxn],v[maxn];
    int fa[maxn],ch[maxn][2];
    bool isroot(int x) {
        return ch[fa[x]][1]!=x&&ch[fa[x]][0]!=x;
    }
    void update(int x){
        ans[x]=ans[lc]^ans[rc]^v[x];
    }
    void pushdown(int x) {
         if(rev[x]) {
            rev[x]=0;rev[lc]^=1;rev[rc]^=1;
            std::swap(lc,rc);
         }
         return;
    }
    void rotate(int x) {
        int y=fa[x],z=fa[y],d=(ch[y][1]==x)^1;
        if(!isroot(y)) ch[z][ch[z][1]==y]=x;
        fa[x]=z;
        ch[y][d^1]=ch[x][d],fa[ch[x][d]]=y;
        ch[x][d]=y;fa[y]=x;
        return update(y),update(x);
    }
    void splay(int x) {
        stack[++top]=x;
        for(int i=x;!isroot(i);i=fa[i]) 
            stack[++top]=fa[i];
        while(top)pushdown(stack[top--]);
        while(!isroot(x)) {
            int y=fa[x],z=fa[y];
            if(!isroot(y)) {
                if(ch[y][1]==x^ch[z][1]==y)rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
        return ;
    }
    void access(int x) {
        for(int i=0;x;i=x,x=fa[x]) {
            splay(x),ch[x][1]=i,update(x);
        }
        return ;
    }
    void makeroot(int x) {
        access(x);splay(x);rev[x]^=1;
        return;
    }
    void split(int x,int y) {
        makeroot(x),access(y);return splay(y);
    }
    void cut(int x,int y) {
        split(x,y);
        ch[y][0]=fa[ch[y][0]]=0;
        return;
    }
    void link(int x,int y) {
        makeroot(x),fa[x]=y;return splay(x);
    }
    int find(int x) {
        for(access(x),splay(x);ch[x][0];x=ch[x][0]);
        return x;
    }
    int query(int x,int y) {
        split(x,y);
        return ans[y];
    }
    void modify(int x,int w) {
        access(x),splay(x),v[x]=w;
        return update(x);
    }
    int main() {
        int n,m;
        n=read(),m=read();
        for(int i=1;i<=n;++i) {
            v[i]=read();ans[i]=v[i];
        }
        for(int op,x,y,i=1;i<=m;++i) {
            op=read(),x=read(),y=read();
            if(!op) 
                printf("%d
    ",query(x,y));
            else if(op==1) {
                if(find(x)!=find(y)) link(x,y);
            }
            else if(op==2) {
                if(find(x)==find(y))cut(x,y);
            }
            else modify(x,y);
        }
        return 0;
    }
  • 相关阅读:
    Splunk 8.2.4破解每日500M限制
    wargame之Natas解题过程记录
    Linux提权方法小结
    Splunk安装
    从原理学习Java反序列化
    getshell之后
    VulnStack靶机练习
    eclipse 3.7安装扩展心得
    yarn 切换node版本
    Rreact如何调取后端接口发起PC端项目支付宝支付请求?
  • 原文地址:https://www.cnblogs.com/sssy/p/8150952.html
Copyright © 2020-2023  润新知