社区讨论

MnZn求助,和题解拍了十几次都没出问题

SP16549QTREE6 - Query on a tree VI参与者 2已保存回复 2

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@mhjstteg
此快照首次捕获于
2025/11/04 07:56
4 个月前
此快照最后确认于
2025/11/04 07:56
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
#define ll int
#define rs(x) son[x][1]
#define ls(x) son[x][0]
// #define get(x) (rs(fa[x]) == x)
// #define isroot(x) (ls(fa[x]) != x && rs(fa[x]) != x)
#define MAXN 1000010
inline ll read(){
    ll f = 1, num = 0;
    char c = getchar();
    while(c < '0' || c > '9'){
        if(c=='-') f = -1;c = getchar();
     }
    while(c>='0'&&c<='9') num = num * 10 + c - '0', c = getchar();
    return num * f;
}

ll n;

struct node_LCT{
    ll son[MAXN][2],fa[MAXN],tag[MAXN];
    ll sz[MAXN],szp[MAXN];
    void push_up(ll x){
        sz[x] = sz[ls(x)] + sz[rs(x)] + (x <= n) + szp[x];
    }

    void init(){
        for(int i = 1;i <= n; ++i)sz[i] = 1;
    }

    // void push_down(ll x){
    //     if(!tag[x])return;
    //     swap(ls(ls(x)), rs(ls(x)));
    //     swap(ls(rs(x)), rs(rs(x)));
    //     tag[ls(x)] ^= 1;
    //     tag[rs(x)] ^= 1;
    //     tag[x] = 0;
    // }

    bool get(ll x){
        return rs(fa[x]) == x;
    }

    bool isroot(ll x){
        return ls(fa[x]) != x && rs(fa[x]) != x;
    }

    void rot(ll x){
        ll y = fa[x],z = fa[y];
        ll fx = get(x),fy = get(y);
        if(!isroot(y))son[z][fy] = x;
        son[y][fx] = son[x][fx ^ 1];
        son[x][fx ^ 1] = y;
        fa[son[y][fx]] = y;
        fa[y] = x,fa[x] = z;
        push_up(y), push_up(x);
    }

    void splay(ll x){
        // update(x);
        while(!isroot(x)){
            ll y = fa[x];
            if(isroot(y))rot(x);
            else{
                if(get(x) == get(y))rot(y);
                else rot(x);
                rot(x);
            }
        }
    }

    void access(ll x){
        for(int p = 0; x; p = x, x = fa[x]){
            splay(x);
            szp[x] -= sz[p];
            szp[x] += sz[rs(x)];
            rs(x) = p;
            push_up(x);
        }
    }

    
    // void makeroot(ll x){
    //     access(x);
    //     splay(x);
    //     swap(ls(x), rs(x));
    //     tag[x] ^= 1;
    // }

    ll findroot(ll x){
        access(x);
        splay(x);
        while(ls(x))x = ls(x);
        splay(x);
        return x;
    }
    
    void link(ll x, ll y){ // x 连接到 y
        access(x),splay(x);
        access(y),splay(y);
        fa[x] = y;
        szp[y] += sz[x];
        push_up(y);
    }

    void cut(ll x, ll y){ // 删除 x 连接到 y 的边
        access(x);
        splay(y);
        fa[rs(y)] = rs(y) = 0;
        push_up(y);
    }

    
    ll query(ll x, ll y){
        access(x);
        splay(y);
        return sz[rs(y)];
    }
}LCT[2];

// ll x[MAXN],y[MAXN]
ll fa[MAXN];
ll q;
ll col[MAXN];
vector <ll> e[MAXN];

void dfs(ll now, ll p){
    fa[now] = p;
    for(int i = 0;i < e[now].size(); ++i){
        ll y = e[now][i];
        if(y == p)continue;
        dfs(y, now);
    }
}

int main(){
    // freopen("w.in", "r", stdin);
    // freopen("Qtree.out", "w", stdout);
    n = read();
    LCT[0].init(),LCT[1].init();
    // return 0;
    auto st = clock();    
    for(int i = 1;i < n; ++i){
        ll x = read(),y = read();
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs(1, n + 1);
    for(int i = 1;i <= n; ++i){
        LCT[col[i] = 0].link(i, fa[i]);
    }


    q = read();
    for(int i = 1;i <= q; ++i){
        ll op = read();
        if(op == 0){
            ll x = read();
            ll tp = LCT[col[x]].findroot(x);
            // cout << "query : " << tp << " ";
            cout << LCT[col[x]].query(x, tp) << endl;
        }else if(op == 1){
            ll x = read();
            LCT[col[x]].cut(x, fa[x]);
            col[x] ^= 1;
            LCT[col[x]].link(x, fa[x]);
        }
    }
    auto ed = clock();
    // cerr << (double)(ed - st) / CLOCKS_PER_SEC << endl;
    return 0;
}

和 @disposrestfully 的题解代码拍了十几次没有问题,调一上午了救救孩子吧

回复

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

正在加载回复...