Submission #1307497

#TimeUsernameProblemLanguageResultExecution timeMemory
1307497Born_To_LaughKlasika (COCI20_klasika)C++17
33 / 110
778 ms589824 KiB
// Born_To_Laugh - Hughie Do
#include <bits/stdc++.h>
#define alle(AC) AC.begin(), AC.end()
#define fi first
#define se second
using namespace std;
typedef long long ll;
#define int ll
[[maybe_unused]] const ll MOD = 998244353, INF = 1e9 + 7;
struct trie
{
    struct node {
        int exist = 0;
        array<int, 2> child;
        node(){
            child.fill(-1);
        }
    };
    int id = 0;
    vector<node> tree;
    trie(){
        tree.emplace_back();
    }
    int new_node(){
        id++;
        if(id >= tree.size()){
            tree.push_back(node());
        }
        return id;
    }
    void add(int a){
        int pos = 0;
        for(int i=30; i>=0; --i){
            int val = (a >> i) & 1;
            if(tree[pos].child[val] == -1){
                tree[pos].child[val] = new_node();
            }
            pos = tree[pos].child[val];
        }
        tree[pos].exist++;
    }
    int walk(int a){
        int pos = 0;
        int ans = 0;
        for(int i=30; i>=0; --i){
            int val = 1 - ((a >> i) & 1);
            if(tree[pos].child[val] != -1){
                pos = tree[pos].child[val];
                ans |= (val << i);
            }
            else if(tree[pos].child[1 - val] != -1){
                pos = tree[pos].child[1 - val];
                ans |= ((1 - val) << i);
            }
            else break;
        }
        if(tree[pos].exist > 0)return ans;
        else return a;
    }
};
struct segtree
{
    int n;
    vector<trie> tree;
    void init(int len){
        n = len;
        tree.assign(n << 1, trie());
    }
    void PointUpd(int pos, int val){
        pos += n - 1;
        for(; pos >= 1; pos >>= 1){
            tree[pos].add(val);
        }
    }
    int qr(int l, int r, int val){
        l += n - 1;r += n - 1;
        int ans = val;
        for(; l <= r; l >>= 1, r >>= 1){
            if(l & 1){
                if((ans ^ val) < (tree[l].walk(val) ^ val)){
                    ans = tree[l].walk(val);
                }
                l++;
            }
            if(!(r & 1)){
                if((ans ^ val) < (tree[r].walk(val) ^ val)){
                    ans = tree[r].walk(val);
                }
                r--;
            }
        }
        return ans;
    }
};

const int maxn = 2e5 + 10;
int n = 1, q;
int xorr[maxn];//xor 1 -> a = xorr[a]

vector<vector<int>> qr;
vector<int> adj[maxn];
int tin[maxn], tout[maxn];
int eul = 0;
segtree st;


void dfs(int a){
    tin[a] = ++eul;
    for(auto &elm: adj[a]){
        dfs(elm);
    }
    tout[a] = eul;
}
void ope1(vector<int> cc){
    int a = cc[1], n = cc[2], b = cc[3];
    xorr[n] = xorr[a] ^ b;
    st.PointUpd(tin[n], xorr[n]);
}
int ope2(vector<int> cc){
    int a = cc[1], b = cc[2];
    return xorr[a] ^ st.qr(tin[b], tout[b], xorr[a]);
}
void solve(){
    cin >> q;
    for(int i=1; i<=q; ++i){
        string x;cin >> x;
        int a, b;cin >> a >> b;
        if(x[0] == 'A'){
            adj[a].push_back(++n);
            qr.push_back({1, a, n, b});
        }
        else qr.push_back({2, a, b});
    }
    st.init(n + 3);
    dfs(1);
    st.PointUpd(tin[1], 0);
    for(auto &elm: qr){
        if(elm[0] == 1){
            ope1(elm);
        }
        else cout << ope2(elm) << '\n';
    }
}
signed main(){
    // freopen("inp.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    solve();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...