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


    Code:

    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<cstring>
    using namespace std;
    void setIO(string a){ freopen((a+".in").c_str(),"r",stdin);}
    struct LCT{
        #define maxn 400007
        #define lson ch[o][0]
        #define rson ch[o][1]
        int ch[maxn][2], f[maxn], val[maxn], tag[maxn], sta[maxn], sumv[maxn];
        int get(int x){ return ch[f[x]][1] == x; }
        int Isroot(int x){ return !(ch[f[x]][0] == x || ch[f[x]][1] == x); }
        void pushup(int o) {sumv[0] = 0, sumv[o] = sumv[lson] ^ sumv[rson] ^ val[o], sumv[0] = 0; }
        void mark(int x){ if(x) swap(ch[x][0], ch[x][1]), tag[x] ^= 1;}
        void pushdown(int o) { if(tag[o]) mark(lson), mark(rson), tag[o] ^= 1;}
        void rotate(int o){
            int old = f[o], fold = f[old], which = get(o);
            if(!Isroot(old)) ch[fold][ch[fold][1] == old] = o;
            f[o] = fold;
            ch[old][which] = ch[o][which^1], f[ch[old][which]] = old;
            ch[o][which^1] = old, f[old] = o;
            pushup(old), pushup(o), pushup(fold);
        }
        void splay(int o){
            int v = 0, u;
            sta[++v] = o, u = o;
            while(!Isroot(u)) sta[++v] = f[u], u = f[u];
            while(v) pushdown(sta[v--]);
            u = f[u];
            for(int fa;(fa=f[o]) != u;rotate(o))
                if(f[fa] != u) rotate(get(fa)==get(o)?fa:o);
        }
        void Access(int u){ for(int y=0;u;y=u,u=f[u]) splay(u), ch[u][1]=y, pushup(u); }                              
        void makeRoot(int u){ Access(u), splay(u), mark(u); }
        void split(int x,int y){ makeRoot(x), Access(y),splay(y);}
        int findRoot(int x){
            int u = x;
            Access(x), splay(x);
            while(x) u = x, pushdown(x), x=ch[x][0];
            return u;
        }
        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 && ch[y][0] == x && !ch[x][1]) {
                f[x] = ch[y][0] = 0;
                pushup(y);
            }
        }
    }tree;
    int main(){  
        //setIO("input");
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n; ++i) scanf("%d",&tree.val[i]), tree.sumv[i]=tree.val[i];
        for(int i = 1;i <= m; ++i){
            int opt,x, y; 
            scanf("%d%d%d",&opt,&x,&y);
            switch(opt){
                case 0: { tree.split(x,y), printf("%d
    ",tree.sumv[y]);  break; }
                case 1: { tree.link(x,y);  break; }
                case 2: { tree.cut(x,y);  break; }
                case 3: { tree.splay(x), tree.val[x] = y, tree.pushup(x); break; }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    ipv6 for openwrt odhcpd
    openwrt package Makefile
    openwrt 中个网络接口协议说明[转]
    openwrt Package aircrack-ng is missing dependencies for the following libraries:
    linux kernel 从cmdline 提取值
    js 上传文件进度条 [uboot使用]
    printk打印级别 [转]
    linux c 宏定义
    uboot 开发记录
    mac ssh scp命令
  • 原文地址:https://www.cnblogs.com/guangheli/p/10003153.html
Copyright © 2020-2023  润新知