• LCT 第一题 洛谷模板


    LCT 第一题

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

    LCT第一题,模板来自题解的博客,也是我学会LCT看的博客ORZ

    存一下好找。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN = 5e5 + 10;
    typedef long long LL;
    
    #define fa(x) T[x].f
    #define ls(x) T[x].ch[0]
    #define rs(x) T[x].ch[1]
    
    int v[MAXN];
    
    struct node {
        int f, ch[2], s;
    
        bool r;
    } T[MAXN];
    
    inline int read() {
        char c = getchar();int x = 0,f = 1;
        while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
        while(c >= '0' && c <= '9') { x = x * 10 + c - '0', c = getchar(); }
        return x * f;
    }
    
    int ident(int x) {
        return T[fa(x)].ch[0] == x ? 0 : 1;
    }
    
    int connect(int x, int fa, int how) {
        T[x].f = fa;
        T[fa].ch[how] = x;
    }
    
    inline bool isRoot(int x) { //若为splay中的根则返回1 否则返回0
        return ls( fa(x) ) != x && rs( fa(x) ) != x;
        //用到了两个性质
        //1.若x与fa(x)之间的边是虚边,那么它的父亲的孩子中不会有他(不在同一个splay内)
        //2. splay的根节点与其父亲之间的边是虚边
    }
    
    void push_up(int x) {
        T[x].s = T[ls(x)].s ^ T[rs(x)].s ^ v[x]; //维护路径上的异或和
    }
    
    void push_down(int x) {
        if(T[x].r) {
            swap(ls(x),rs(x));
            T[ls(x)].r ^= 1;
            T[rs(x)].r ^= 1;
            T[x].r = 0;
        }
    }
    
    void rotate(int x) {
        int Y = T[x].f, R = T[Y].f, Yson = ident(x), Rson = ident(Y);
        int B = T[x].ch[Yson ^ 1];
        T[x].f = R;
        if(!isRoot(Y)) {
            connect(x, R, Rson);
        }
        connect(B, Y, Yson);
        connect(Y, x, Yson ^ 1);
        push_up(Y); push_up(x);
    }
    
    int st[MAXN];
    
    void splay(int x) {
        int y = x, top = 0;
        st[++top] = y;
        while(!isRoot(y)) { st[++top] = y = fa(y); }
        while(top) { push_down(st[top--]); }
        for(int y = fa(x); !isRoot(x); rotate(x), y = fa(x)) {
            if(!isRoot(y)) {
                rotate( ident(x) == ident(y) ? x : y );
            }
        }
    }
    
    void access(int x) {
        for(int y = 0; x; x = fa(y = x)) {
            splay(x), rs(x) = y, push_up(x);
        }
    }
    
    void make_root(int x) {
        access(x);
        splay(x);
        T[x].r ^= 1;
        push_down(x);
    }
    
    int find_root(int x) {
        access(x); splay(x); push_down(x);
        while(ls(x)) { push_down(x = ls(x)); }
        return x;
    }
    
    void split(int x, int y) {
        make_root(x); access(y); splay(y);
    }
    
    void link(int x, int y) {
        make_root(x);
        if(find_root(y) != x) {
            fa(x) = y;
        }
    }
    
    void cut(int x, int y) {
        make_root(x);
        if(find_root(y) == x && fa(x) == y && ls(y) == x && !rs(x)) {
            fa(x) = T[y].ch[0] = 0;
            push_up(y);
        }
    }
    
    int main()
    {
        int N = read(), M = read();
        for(int i = 1; i <= N; i++) v[i] = read();
        for(int i = 1; i <= M; i++) {
            int opt = read(), x = read(), y = read();
            if(opt == 0) split(x, y), printf("%d
    ",T[y].s);
            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;
    }
    
    
    
  • 相关阅读:
    linux安装mongodb(设置非root用户和开机启动)
    Dubbo与Kubernetes集成
    利用Arthas定位线上问题实例
    利用JVM在线调试工具排查线上问题
    用Python写算法题--洛谷P1149 火柴棒等式
    通过实例理解Java网络IO模型
    Http协议Content-Length详解
    异步处理ServletRequest引发的血案
    漫谈递归和迭代
    ThinkPad笔记本外放没声音解决办法(不是驱动的原因)
  • 原文地址:https://www.cnblogs.com/Q1143316492/p/9509560.html
Copyright © 2020-2023  润新知