제출 #1352285

#제출 시각아이디문제언어결과실행 시간메모리
1352285chithanhnguyenKlasika (COCI20_klasika)C++20
110 / 110
2920 ms460732 KiB
#include <bits/stdc++.h>
using namespace std;

// #define int long long
#define ull unsigned long long
#define ld long double
#define pii pair<int, int>
#define fi first
#define se second
#define __builtin_popcount __builtin_popcountll
#define all(x) (x).begin(), (x).end()
#define BIT(x, i) (((x) >> (i)) & 1)
#define MASK(x) ((1ll << (x)))

#define debug(a, l, r) for (int _i = (l); _i <= (r); ++_i) cout << (a)[_i] << ' '; cout << '\n';

const int MAXCHAR = 2;
const int LG = 30;
const int INF = 1e9 + 5;
// 

void minimize(int &x, int y) {
    if (x > y) x = y;
}

struct Node{
    vector<Node*> child;
    int time = INF;

    Node() {
        child.resize(2, nullptr);
    }
};

struct BinaryTrie{
    Node root;
    vector<pii> nums;

    BinaryTrie() {
        root = Node();
    }

    void reset() {
        clearNode(&root);
        root = Node();
        nums.clear();
    }

    void clearNode(Node* node) {
        if (!node) return;
        for (int i = 0; i < MAXCHAR; ++i) {
            if (node->child[i]) {
                clearNode(node->child[i]);
                delete node->child[i];
                node->child[i] = nullptr;
            }
        }
    }

    void addNum(int x, int t) {
        nums.push_back({x, t});
        Node *cur = &root;
        minimize(cur->time, t);
        for (int i = LG; i >= 0; --i){
            int c = BIT(x, i);
            if (!(cur->child[c])) cur->child[c] = new Node();
            cur = cur->child[c];
            minimize(cur->time, t);
        }
    }

    int findMaximumXor(int x, int t) {
        Node *cur = &root;
        int res = 0;

        for (int i = LG; i >= 0; --i) {
            int need = BIT(x, i) ^ 1;
            if (!(cur->child[need])) need ^= 1;
            else {
                if (cur->child[need]->time > t) need ^= 1;
            }
            res += MASK(i) * (need ^ BIT(x, i));
            cur = cur->child[need];
        }

        return res;
    }
};

struct Query{
    int a, time;
};

const int MAXN = 2e5 + 5;
vector<pii> adj[MAXN];
int q, n, appear[MAXN], f[MAXN];
// int st[MAXN], en[MAXN], timer = 0;
vector<Query> queries[MAXN];
BinaryTrie trie[MAXN];
int ans[MAXN];

void dfs(int u, int par = 0) {
    // st[u] = ++timer;

    for (auto &e : adj[u]) {
        int v = e.fi, w = e.se;

        if (v == par) continue;

        f[v] = f[u] ^ w;
        dfs(v, u);
    }

    // en[u] = timer;
}

void init() {
    cin >> q; n = 1;
    memset(ans, -1, sizeof ans);
    for (int i = 1; i <= q; ++i) {
        string type; cin >> type;
        int a, b; cin >> a >> b;
        if (type == "Add") {
            adj[a].push_back({n + 1, b});
            adj[n + 1].push_back({a, b});
            ++n;
            appear[n] = i;
        } 
        else {
            queries[b].push_back({a, i});
        }
    }

    dfs(1);
    // for (int i = 1; i <= n; ++i) {
    //     // cout << st[i] << ' ' << en[i] << '\n';
    //     // cout << appear[i] << '\n';
    //     // cout << f[i] << '\n';
    //     // cout << "dfsdf:\n";
    //     addNum(f[i], st[i], en[i], appear[i]);
    // }
}

void dfs_solve(int u, int par = -1) {
    for (auto &e : adj[u]) {
        int v = e.fi;
        if (v == par) continue;
        dfs_solve(v, u);

        if (trie[u].nums.size() < trie[v].nums.size())
            swap(trie[u], trie[v]);
        for (auto &p : trie[v].nums) 
            trie[u].addNum(p.fi, p.se);
        trie[v].reset();
    }

    for (auto &qry : queries[u]) {
        int a = qry.a, time = qry.time;
        // cout << i << ' ' << a << ' ' << time << '\n';
        ans[time] = trie[u].findMaximumXor(f[a], time);
    }
}

void solve() {
    // debug(f, 1, n);
    // BinaryTrie trie;
    // for (int i = 1; i <= n; ++i) {
    //     trie.reset();
    //     for (int j = 1; j <= n; ++j) {
    //         if (st[i] <= st[j] && st[j] <= en[i])
    //             trie.addNum(f[j], appear[j]);
    //     }

    //     for (auto &qry : queries[i]) {
    //         int a = qry.a, time = qry.time;
    //         // cout << i << ' ' << a << ' ' << time << '\n';
    //         ans[time] = trie.findMaximumXor(f[a], time);
    //     }
    // }
    for (int u = 1; u <= n; ++u) trie[u].addNum(f[u], appear[u]);
    dfs_solve(1);
    for (int i = 1; i <= q; ++i)
        if (ans[i] != -1) cout << ans[i] << '\n';
}

signed main() {
    #ifdef NCTHANH
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr); cout.tie(nullptr);

    init();
    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...