Submission #770068

#TimeUsernameProblemLanguageResultExecution timeMemory
770068vjudge1Klasika (COCI20_klasika)C++17
0 / 110
5084 ms231668 KiB
#include <bits/stdc++.h> using namespace std; #ifdef LOCAL #include "C:\GCC\debug.h" #else #define debug(...) void(42) #endif const int lg = 31; struct Trie { public: vector<vector<int>> trie; vector<int> values; map<int, bool> used; Trie() { trie.push_back(vector<int> (2, -1)); values.push_back(0); used[0] = true; }; void add(int x) { if (used[x]) { return ; } used[x] = true; values.push_back(x); int t = 0; for (int i = lg - 1; i >= 0; i--) { int bit = (x >> i) & 1; if (trie[t][bit] == -1) { trie[t][bit] = (int) trie.size(); trie.emplace_back(2, -1); } t = trie[t][bit]; } } int get(int x) { int t = 0; int ret = 0; for (int i = lg - 1; i >= 0; i--) { int bit = (x >> i) & 1; bit ^= 1; if (trie[t][bit] == -1) { bit ^= 1; } else { ret |= (1 << i); } if (trie[t][bit] == -1) { return 0; } t = trie[t][bit]; } return ret; }; }; Trie Merge(Trie a, Trie b) { Trie c; if ((int) a.values.size() > (int) b.values.size()) { swap(a.values, b.values); swap(a.trie, b.trie); } c.values = b.values; c.trie = b.trie; for (int i = 0; i < (int) a.values.size(); i++) { c.add(a.values[i]); } return c; } class segTree { public: int n; vector<Trie> st; segTree(int _n) : n(_n) { st.resize(n * 4); } void update(int v, int l, int r, int pos, int nv) { if (l == r) { st[v].add(nv); return ; } int mid = l + (r - l) / 2; if (pos <= mid) { update(v * 2, l, mid, pos, nv); } else { update(v * 2 + 1, mid + 1, r, pos, nv); } st[v] = Merge(st[v * 2], st[v * 2 + 1]); } int get(int v, int l, int r, int low, int high, int p) { if (l == low && r == high) { return st[v].get(p); } int mid = l + (r - l) / 2; if (high <= mid) { return get(v * 2, l, mid, low, high, p); } else if (low > mid) { return get(v * 2 + 1, mid + 1, r, low, high, p); } else { return max(get(v * 2, l, mid, low, mid, p), get(v * 2 + 1, mid + 1, r, mid + 1, high, p)); } } }; int main() { ios::sync_with_stdio(false); cin.tie(0); int q; cin >> q; int n = q + 1; vector<vector<int>> adj(n); vector<int> pref(n); auto Add = [&](int x, int y, int w) { adj[x].push_back(y); pref[y] = pref[x] ^ w; }; int cnt = 1; vector<array<int, 3>> queries; for (int i = 0; i < q; i++) { string type; cin >> type; if (type == "Add") { int x, w; cin >> x >> w; --x; Add(x, cnt, w); queries.push_back({1, cnt, 0}); ++cnt; } else { int a, b; cin >> a >> b; --a, --b; queries.push_back({2, a, b}); } } vector<int> in(n); vector<int> out(n); vector<int> euler_tour; function<void(int)> Dfs = [&](int u) { in[u] = (int) euler_tour.size(); euler_tour.push_back(u); for (auto v : adj[u]) { Dfs(v); } out[u] = (int) euler_tour.size() - 1; }; Dfs(0); segTree st(n); st.update(1, 0, n - 1, in[0], 0); for (int i = 0; i < (int) queries.size(); i++) { int type = queries[i][0]; if (type == 1) { int u = queries[i][1]; st.update(1, 0, n - 1, in[u], pref[u]); } else { int a = queries[i][1]; int b = queries[i][2]; cout << st.get(1, 0, n - 1, in[b], out[b], pref[a]) << '\n'; } } 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...