zoukankan      html  css  js  c++  java
  • P3690 【模板】Link Cut Tree (动态树)

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

    思路

    candy
    不是太掌握
    也落落不太清楚
    自己学习吧
    lmc讲的时候睡着了

    #include<bits/stdc++.h>
    #define ls c[x][0]
    #define rs c[x][1]
    const int N=300009;
    using namespace std;
    int read() {
        int x=0,f=1;char s=getchar();
        for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
        for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
        return x*f;
    }
    int f[N],c[N][2],v[N],s[N],st[N];
    bool lazy[N];
    inline bool isroot(int x){
        return c[f[x]][0]==x||c[f[x]][1]==x;
    }
    void pushup(int x){
        s[x]=s[ls]^s[rs]^v[x];
    }
    void tag(int x){swap(ls,rs);lazy[x]^=1;}
    void pushdown(int x){
        if(lazy[x]){
            if(ls)tag(ls);
            if(rs)tag(rs);
            lazy[x]=0;
        }
    }
    void rotate(int x){
        int y=f[x],z=f[y],k=c[y][1]==x,w=c[x][!k];
        if(isroot(y))c[z][c[z][1]==y]=x;
        c[x][!k]=y;
        c[y][k]=w;
        if(w)f[w]=y;
        f[y]=x;
        f[x]=z;
        pushup(y);
    }
    void splay(int x){
        int y=x,z=0;
        st[++z]=y;
        while(isroot(y))st[++z]=y=f[y];
        while(z)pushdown(st[z--]);
        while(isroot(x)){
            y=f[x];z=f[y];
            if(isroot(y)) rotate((c[y][0]==x)^(c[z][0]==y)?x:y);
            rotate(x);
        }
        pushup(x);
    }
    void access(int x){
        for(int y=0;x;x=f[y=x])
            splay(x),rs=y,pushup(x);
    }
    void makeroot(int x){
        access(x);splay(x);
        tag(x);
    }
    inline int findroot(int x){
        access(x);splay(x);
        while(ls)pushdown(x),x=ls;
        return x;
    }
    void split(int x,int y){
        makeroot(x);
        access(y);splay(y);
    }
    void link(int x,int y){
        makeroot(x);
        if(findroot(y)!=x)f[x]=y;
    }
    void cut(int x,int y){
        makeroot(x);
        if(findroot(y)==x&&f[x]==y&&!rs){
            f[x]=c[y][0]=0;
            pushup(y);
        }
    }
    int main()
    {
        int n=read(),m=read();
        for(int i=1;i<=n;++i) v[i]=read();
        while(m--){
            int opt=read(),x=read(),y=read();
            if(opt==0){
               split(x,y);
               printf("%d
    ",s[y]);
            } else if(opt==1){
                link(x,y);
            } else if(opt==2) {
                cut(x,y);
            } else if(opt==3) {
                splay(x);v[x]=y;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    net8:XML的读写操作【广告控件的XML文件实例】
    挺喜欢这个网站的
    问的问题的答案~
    zookeeper集群搭建
    solrCloud简介
    e3商城_day07
    solrj实现增删查
    solr后台管理界面-数据导入
    solr后台管理界面-增删改
    s5p6818 从SD卡启动程序(制作SD启动卡)
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10181570.html
Copyright © 2011-2022 走看看