Submission #1173145

#TimeUsernameProblemLanguageResultExecution timeMemory
1173145rayan_bdKlasika (COCI20_klasika)C++17
0 / 110
681 ms589824 KiB
#include <bits/stdc++.h>
using namespace std;

#define getar(ar,n) for(int i=0;i<n;++i) cin>>ar[i]
#define show(n) cout<<n<<'\n'
#define all(v) v.begin(), v.end()
#define pb push_back
#define nl '\n'

const int mxN = 2e5 + 500;

int N=1, idx=0, parent[mxN], depth[mxN], heavy[mxN], head[mxN], sz[mxN], tin[mxN], tout[mxN], seg[mxN*4], val[mxN], till[mxN];
vector<pair<int,int>> adj[mxN];

struct Node {
    Node* children[2];
    Node() {
        children[0] = children[1] = nullptr;
    }
};

struct Trie {
    Node* root;
    Trie() { root = new Node(); }

    void add(int x) {
        Node* curr = root;
        for (int i = 30; i >= 0; --i) {
            int bit = (x >> i) & 1;
            if (!curr->children[bit]) {
                curr->children[bit] = new Node();
            }
            curr = curr->children[bit];
        }
    }

    int qry(int x) {
        Node* curr = root;
        int ans = 0;
        for (int i = 30; i >= 0; --i) {
            int bit = (x >> i) & 1;
            if (curr->children[1 - bit]) {
                curr = curr->children[1 - bit];
                ans |= (1 << i);
            } else {
                curr = curr->children[bit];
            }
        }
        return ans;
    }
};

unordered_map<int, Trie> t;

struct SegTree {
    void update_1(int node, int start, int end, int idx, int val) {
        if (start == end) {
            seg[node] = val;
            return;
        }
        int mid = (start + end) / 2;
        if (idx <= mid) update_1(2 * node + 1, start, mid, idx, val);
        else update_1(2 * node + 2, mid + 1, end, idx, val);
        seg[node] = seg[2 * node + 1] ^ seg[2 * node + 2];
    }

    void update_2(int node, int start, int end, int idx, int val) {
        if (!t.count(node)) t[node] = Trie();
        t[node].add(val);
        if (start == end) return;
        int mid = (start + end) / 2;
        if (idx <= mid) update_2(2 * node + 1, start, mid, idx, val);
        else update_2(2 * node + 2, mid + 1, end, idx, val);
    }

    int qry_answer(int node, int start, int end, int l, int r, int val) {
        if (start > r || end < l) return 0;
        if (start >= l && end <= r) return t[node].qry(val);
        int mid = (start + end) / 2;
        return max(qry_answer(2 * node + 1, start, mid, l, r, val), qry_answer(2 * node + 2, mid + 1, end, l, r, val));
    }

    int xor_qry(int node, int start, int end, int l, int r) {
        if (start > r || end < l) return 0;
        if (start >= l && end <= r) return seg[node];
        int mid = (start + end) / 2;
        return xor_qry(2 * node + 1, start, mid, l, r) ^ xor_qry(2 * node + 2, mid + 1, end, l, r);
    }
} seg_tree;

struct HLD {
    void dfs(int u = 1, int par = 0) {
        sz[u] = 1;
        parent[u] = par;
        depth[u] = depth[par] + 1;
        for (auto it : adj[u]) {
            if (it.first != par) {
                val[it.first] = it.second;
                dfs(it.first, u);
                sz[u] += sz[it.first];
                if (sz[heavy[u]] < sz[it.first]) heavy[u] = it.first;
            }
        }
    }

    void dfsHLD(int u = 1, int chain = 1) {
        head[u] = chain;
        tin[u] = idx++;
        seg_tree.update_1(0, 0, N - 1, tin[u], val[u]);
        if (heavy[u]) dfsHLD(heavy[u], chain);
        for (auto it : adj[u]) {
            if (it.first != parent[u] && it.first != heavy[u]) {
                dfsHLD(it.first, it.first);
            }
        }
        tout[u] = idx - 1;
    }

    int path_xor(int u, int v) {
        int ans = 0;
        while (head[u] != head[v]) {
            if (depth[head[u]] < depth[head[v]]) swap(u, v);
            ans ^= seg_tree.xor_qry(0, 0, N - 1, tin[head[u]], tin[u]);
            u = parent[head[u]];
        }
        if (depth[u] < depth[v]) swap(u, v);
        return (ans ^ seg_tree.xor_qry(0, 0, N - 1, tin[v], tin[u])) ^ val[v];
    }
} hld;

void lets_go() {
    int q, u, v;
    cin >> q;
    string type;
    vector<vector<int>> Q;
    for (int i = 0; i < q; ++i) {
        cin >> type >> u >> v;
        if (type == "Add") {
            Q.pb({1, u, ++N, v});
            adj[u].pb({N, v});
        } else {
            Q.pb({0, u, v});
        }
    }

    hld.dfs();
    hld.dfsHLD();
    t[0].add(0);

    for (auto it : Q) {
        if (it[0] == 1) {
            till[it[2]] = till[it[1]] ^ it[3];
            seg_tree.update_2(0, 0, N - 1, tin[it[2]], till[it[2]]);
        } else {
            u = it[1], v = it[2];
            show(seg_tree.qry_answer(0, 0, N - 1, tin[v], tout[v], hld.path_xor(u, v) ^ till[v]));
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    lets_go();
    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...