제출 #1332055

#제출 시각아이디문제언어결과실행 시간메모리
1332055halzoomKlasika (COCI20_klasika)C++20
0 / 110
122 ms155176 KiB
#include <bits/stdc++.h>

using namespace std;
#define int long long
const int inf = 1e18, N = 2e5 + 5;

struct LCA {
    vector<vector<int>> ancestor;
    vector<int> level;
    int LG;

    LCA() {};

    LCA(vector<vector<int>> &adj) {
        int n = (int) adj.size();
        LG = __lg(n) + 1;
        ancestor.assign(LG, vector<int>(n));
        level.assign(n, {});
        build(1, 0, adj);
        for (int i = 1; i < LG; ++i) {
            for (int u = 1; u < n; ++u) {
                ancestor[i][u] = ancestor[i - 1][ancestor[i - 1][u]];
            }
        }
    }

    void build(int u, int p, vector<vector<int>> &adj) {
        for (auto v: adj[u]) {
            if (v == p) continue;
            level[v] = level[u] + 1;
            ancestor[0][v] = u;
            build(v, u, adj);
        }
    }

    int KthAnc(int u, int k) {
        for (int i = 0; k; ++i, k >>= 1) {
            if (k & 1) u = ancestor[i][u];
        }
        return u;
    }

    int getLCA(int u, int v) {
        if (level[u] > level[v]) swap(u, v);
        int k = level[v] - level[u];
        v = KthAnc(v, k);
        if (v == u) return v;
        for (int i = LG - 1; ~i; --i) {
            if (ancestor[i][v] != ancestor[i][u]) {
                v = ancestor[i][v];
                u = ancestor[i][u];
            }
        }
        return ancestor[0][u];
    }
} T;

struct Trie_B {
    struct Node {
        int child[2]{};
        int cnt = 0, isEnd = 0, minT = inf;

        int &operator[](int x) { return child[x]; }
    };

    vector<pair<int, int>> val;
    vector<Node> node;

    Trie_B() { node.emplace_back(); }

    int newNode() {
        node.emplace_back();
        return node.size() - 1;
    }

    int sz(int x) { return node[x].cnt; }

    int M = 30;

    void update(int x, int time, int op) {  // op -> 1 add || op -> -1 erase
        int cur = 0;
        val.emplace_back(x, time);
        for (int i = M - 1; i >= 0; --i) {
            int c = x >> i & 1;
            if (node[cur][c] == 0) node[cur][c] = newNode();
            cur = node[cur][c];
            node[cur].cnt += op;
            node[cur].minT = min(time, node[cur].minT);
        }
        node[cur].isEnd += op;
    }

    int max_xor(int x, int timer) {
        int cur = 0, res = 0;
        for (int i = M - 1; i >= 0; --i) {
            int cx = (x >> i) & 1;
            int target = !cx;
            int nxt = node[cur][target];

            if (nxt != 0 and node[nxt].cnt > 0 and node[nxt].minT <= timer) {
                res |= (1LL << i);
                cur = nxt;
            } else {
                cur = node[cur][cx];
                if (cur == 0 || node[cur].minT > timer)
                    assert(0);
            }
        }
        return res;
    }
};

int answer[N];
vector<vector<int>> adj;
vector<int> timer, a, b;
vector<vector<array<int, 3>>> Q;

void dfs(int u, int p) {
    for (auto v: adj[u]) {
        if (v == p)continue;
        a[v] ^= a[u];
        dfs(v, u);
    }
}

Trie_B go(int u, int p) {
    Trie_B all;
    all.update(a[u], timer[u], 1);
    for (auto v: adj[u]) {
        if (v == p)continue;
        auto cur = go(v, u);
        if (all.val.size() < cur.val.size())swap(all, cur);
        for (auto [b, t]: cur.val)
            all.update(b, t, 1);
    }

    for (auto [nd, idx, time]: Q[u]) {
        int lc = T.getLCA(nd, u);
        answer[idx] = all.max_xor(a[nd], time ^ b[lc]);
    }
    return all;
}

void solve() {
    int q;
    cin >> q;
    adj.assign(q + 1, {});
    timer.assign(q + 1, {});
    a.assign(q + 1, {});
    timer[1] = inf;
    Q.assign(q + 1, {});
    int id = 2, cnt = 1;
    for (int i = 1; i <= q; ++i) {
        string s;
        cin >> s;
        if (s[0] == 'A') {
            int u, x;
            cin >> u >> x;
            a[id] = x;
            timer[id] = i;
            adj[u].emplace_back(id++);
        } else {
            int u, v;
            cin >> u >> v;
            Q[v].push_back({u, cnt++, i});
        }
    }
    b = a;
    T = LCA(adj);
    dfs(1, 0);
    go(1, 0);
    for (int i = 1; i < cnt; ++i)
        cout << answer[i] << '\n';
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
#ifdef HALZOOM
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif

    int test = 1;
//    cin >> test;

    for (int i = 1; i <= test; ++i) {
        solve();
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...