社区讨论

30pts 求调

P3690【模板】动态树(LCT)参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mje4z6ey
此快照首次捕获于
2025/12/20 18:09
3 个月前
此快照最后确认于
2025/12/20 19:18
3 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+1;
int n, m, op, x, y;
struct LCT{
    int fa[N], ch[N][2], val[N], sum[N];
    bool rev[N];
    inline bool get(int x){return ch[fa[x]][1] == x;}
    inline bool isroot(int x){return ch[fa[x]][0] != x && ch[fa[x]][1] != x;}
    inline void pushup(int x){sum[x] = sum[ch[x][0]] ^ sum[ch[x][1]] ^ val[x];}
    inline void pushrev(int x){
        if (!x) return;
        swap(ch[x][0], ch[x][1]);
        rev[x] ^= 1;
    }
    inline void pushdown(int x){
        if (rev[x]){
            pushrev(ch[x][0]);
            pushrev(ch[x][1]);
            rev[x] = 0;
        }
    }
    inline void rotate(int x){
        int y = fa[x], z = fa[y];
        bool k = get(x);
        if (!isroot(y)) ch[z][get(y)] = x;
        fa[x] = z;
        if (ch[y][k] = ch[x][!k]) fa[ch[y][k]] = y; // 等价于:ch[y][k] = ch[x][!k]; if (ch[x][!k]) fa[ch[x][!k]] = y;
        ch[x][!k] = y;
        fa[y] = x;
        pushup(y);
        pushup(x);
    }
    inline void splay(int x){
        static int st[N];
        int top = 1, y = x;
        st[1] = y;
        while(!isroot(y)){
            y = fa[y];
            st[++top] = y;
        }
        while(top) pushdown(st[top--]);
        while(!isroot(x)){
            int y = fa[x];
            if (!isroot(y)) rotate(get(x)^get(y) ? x : y);
            rotate(x);
        }
    }
    inline int access(int x){
        int p = 0;
        while(x){
            splay(x);
            ch[x][1] = p;
            p = x;
            x = fa[x];
        }
        return p;
    }
    inline void makeroot(int x){
        access(x);
        splay(x);
        pushrev(x);
    }
    inline int find(int x){
        pushdown(x = access(x));
        while(ch[x][0]) pushdown(x = ch[x][0]);
        splay(x);
        return x;
    }
    inline void split(int x, int y){
        makeroot(x);
        access(y);
        splay(y);
    }
    inline bool link(int x, int y){
        makeroot(x);
        if (find(y) == x) return false;
        splay(x);
        fa[x] = y;
        return true;
    }
    inline bool cut(int x, int y){
        makeroot(x);
        access(y);
        splay(y);
        if(ch[y][0] != x || ch[x][1]) return false;
        ch[y][0] = fa[x] = 0;
        pushup(y);
        return true;
    }
} T;

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;++i) cin>>T.val[i];
    while(m--){
        cin>>op>>x>>y;
        if (op==0){
            if (x==y){
                cout << T.val[x] << '\n';
                continue;
            }
            T.split(x, y);
            cout << T.sum[y] << '\n';
        } else if (op==1) T.link(x, y);
        else if (op==2) T.cut(x, y);
        else{
            T.makeroot(x);
            T.val[x] = y;
            T.pushup(x);
        }
    }
}

回复

0 条回复,欢迎继续交流。

正在加载回复...