• 模板汇总——LCT


    link-cut tree

    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    const int N = 5e5 + 100;
    struct Node{
        int rev, rt;
        int son[2], pre;
        int mx, val, id;
        void init(){
            rt = 1; rev = pre = son[0] = son[1] = 0;
            mx = val = id = 0;
        }
    }tr[N];
    void Push_Rev(int x){
        if(!x) return ;
        swap(lch(x), rch(x));
        tr[x].rev ^= 1;
    }
    void Push_Up(int x){
        if(!x) return ;
        tr[x].mx = tr[x].val, tr[x].id = x;
        if(tr[x].mx < tr[lch(x)].mx) tr[x].mx = tr[lch(x)].mx, tr[x].id = tr[lch(x)].id;
        if(tr[x].mx < tr[rch(x)].mx) tr[x].mx = tr[rch(x)].mx, tr[x].id = tr[rch(x)].id;
    }
    void Push_Down(int x){
       if(tr[x].rev){
            tr[x].rev = 0;
            Push_Rev(lch(x));
            Push_Rev(rch(x));
        }
    }
    void Rev(int x){
        if(!tr[x].rt) Rev(tr[x].pre);
        Push_Down(x);
    }
    void rotate(int x){
        if(tr[x].rt) return;
        int y = tr[x].pre, z = tr[y].pre;
        int k = (rch(y) == x);
        tr[y].son[k] = tr[x].son[k^1];
        tr[tr[y].son[k]].pre = y;
        tr[x].son[k^1] = y;
        tr[y].pre = x;
        tr[x].pre = z;
        if(tr[y].rt) tr[y].rt = 0, tr[x].rt = 1;
        else tr[z].son[rch(z) == y] = x;
        Push_Up(y);
    }
    void Splay(int x){
         Rev(x);
         while(!tr[x].rt){
            int y = tr[x].pre, z = tr[y].pre;
            if(!tr[y].rt){
                if(( x == rch(y) ) != (y == rch(z))) rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
        Push_Up(x);
    }
    void Access(int x){
        int y = 0;
        do{
            Splay(x);
            tr[rch(x)].rt = 1;
            rch(x) = y;
            tr[y].rt = 0;
            Push_Up(x);
            y = x;
            x = tr[x].pre;
        }while(x);
    }
    void Make_rt(int x){
        Access(x);
        Splay(x);
        Push_Rev(x);
    }
    bool judge(int u, int v){
        while(tr[u].pre) u = tr[u].pre;
        while(tr[v].pre) v = tr[v].pre;
        return u == v;
    }
    void link(int u, int v){
        Make_rt(u);
        tr[u].pre = v;
    }
    void cut(int u, int v){
        Make_rt(u);
        Access(v);
        Splay(v);
        tr[lch(v)].pre = 0;
        tr[lch(v)].rt = 1;
        tr[v].pre = 0;
        lch(v) = 0;
    }
    View Code

    维护子树。

    维护子树就是新开一个状态存一下 所有非偏爱子节点的信息, 然后每次access的时候我们就根据偏爱子节点的变化, 从而更新这个新开的状态。

    这个写法 是维护 子树内的亦或和。

    代码:

    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    const int N = 5e5 + 100;
    struct Node{
        int rev, rt;
        int son[2], pre;
        int sum, vsum, key;
        void init(){
            rt = 1; rev = pre = son[0] = son[1] = 0;
            sum = vsum = key = 0;
        }
    }tr[N];
    void Push_Rev(int x){
        if(!x) return ;
        swap(lch(x), rch(x));
        tr[x].rev ^= 1;
    }
    void Push_Up(int x){
        if(!x) return ;
        tr[x].sum = tr[x].key ^ tr[lch(x)].sum ^ tr[rch(x)].sum ^ tr[x].vsum;
    }
    void Push_Down(int x){
       if(tr[x].rev){
            tr[x].rev = 0;
            Push_Rev(lch(x));
            Push_Rev(rch(x));
        }
    }
    void Rev(int x){
        if(!tr[x].rt) Rev(tr[x].pre);
        Push_Down(x);
    }
    void rotate(int x){
        if(tr[x].rt) return;
        int y = tr[x].pre, z = tr[y].pre;
        int k = (rch(y) == x);
        tr[y].son[k] = tr[x].son[k^1];
        tr[tr[y].son[k]].pre = y;
        tr[x].son[k^1] = y;
        tr[y].pre = x;
        tr[x].pre = z;
        if(tr[y].rt) tr[y].rt = 0, tr[x].rt = 1;
        else tr[z].son[rch(z) == y] = x;
        Push_Up(y);
    }
    void Splay(int x){
         Rev(x);
         while(!tr[x].rt){
            int y = tr[x].pre, z = tr[y].pre;
            if(!tr[y].rt){
                if(( x == rch(y) ) != (y == rch(z))) rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
        Push_Up(x);
    }
    void Access(int x){
        int y = 0;
        do{
            Splay(x);
            tr[rch(x)].rt = 1;
            tr[x].vsum ^= tr[rch(x)].sum;
            rch(x) = y;
            tr[x].vsum ^= tr[rch(x)].sum;
            tr[y].rt = 0;
            Push_Up(x);
            y = x;
            x = tr[x].pre;
        }while(x);
    }
    void Make_rt(int x){
        Access(x);
        Splay(x);
        Push_Rev(x);
    }
    void link(int u, int v){
        Make_rt(u);
        Access(v);
        Splay(v);
        tr[u].pre = v;
        tr[v].
        vsum ^= tr[u].sum;
        Push_Up(v);
    }
    void cut(int u, int v){
        Make_rt(u);
        Access(v);
        Splay(v);
        tr[lch(v)].pre = 0;
        tr[lch(v)].rt = 1;
        tr[v].pre = 0;
        lch(v) = 0;
        Push_Up(v);
    }
    View Code
  • 相关阅读:
    pip安装requests时报 Requirement already satisfied: requests in d:pythonpyth... 的问题解决
    渗透测试靶场
    Spring Security核心类关系图
    Spring security 5 Authorize Configuration
    固定技术栈
    redis 指定端口 启动
    Spring 获取当前activeProfile
    通过进程编号 查询 监听端口
    lombok 插件安装
    idea 快捷键设置
  • 原文地址:https://www.cnblogs.com/MingSD/p/9524806.html
Copyright © 2020-2023  润新知