/*
it could have been better :)
it will next time ;)
*/
#include <bits/stdc++.h>
using namespace std;
#define INF 2e9
#define f first
#define s second
#define pii pair<int, int>
#define vi vector<int>
const int MOD = 1'000'000'000 + 7;
void setIO(string name = "")
{
ios_base::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
#ifdef LOCAL
freopen("inp.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#else
if (!name.empty())
{
freopen((name + ".INP").c_str(), "r", stdin);
freopen((name + ".OUT").c_str(), "w", stdout);
}
#endif
}
struct Trie {
struct Node {
int cnt = 0;
vector<pii> v;
vector<vi> st;
int child[2] = {-1, -1};
void init() {
sort(v.begin(), v.end());
int n = (int)v.size();
int k = __lg((int)v.size()) + 3;
st.resize(n, vi(k + 1));
for(int i = 0; i < n; i++) st[i][0] = v[i].s;
for(int j = 1; j <= k; j++) {
for(int i = 0; i + (1 << j) <= n; i++) {
st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
}
}
}
int query_min(int l, int r) {
int k = __lg(r - l + 1);
return min(st[l][k], st[r - (1 << k) + 1][k]);
}
bool exist(int time_in, int time_out, int time_query) {
auto it1 = lower_bound(v.begin(), v.end(), make_pair(time_in, (int)-1));
auto it2 = upper_bound(v.begin(), v.end(), make_pair(time_out, (int)INF));
if(it1 == v.end()) return false;
int id1 = it1 - v.begin(), id2 = it2 - v.begin();
if(id1 >= id2) return false;
return query_min(id1, id2 - 1) <= time_query;
}
};
vector<Node> trie = {Node()};
void add(int x, pii it) {
int node = 0;
trie[node].v.push_back(it);
for(int b = 30; b >= 0; b--) {
int cur = (x >> b) & 1;
if(trie[node].child[cur] == -1) {
trie[node].child[cur] = trie.size();
trie.emplace_back();
}
node = trie[node].child[cur];
trie[node].v.push_back(it);
}
trie[node].cnt++;
}
int query(int x, int time_in, int time_out, int time_query) {
int node = 0;
int cur_value = 0;
for(int b = 30; b >= 0; b--) {
int cur = 1 - ((x >> b) & 1);
if(trie[node].child[cur] != -1 && trie[trie[node].child[cur]].exist(time_in, time_out, time_query)) node = trie[node].child[cur];
else if(trie[node].child[1 - cur] != -1 && trie[trie[node].child[1 - cur]].exist(time_in, time_out, time_query)) {
node = trie[node].child[1 - cur];
cur = 1 - cur;
}
else return x;
if(cur == 1) cur_value |= (1 << b);
}
if(trie[node].cnt > 0) return cur_value;
return x;
}
void init() {
for(auto &it : trie) it.init();
}
} trie;
struct Query {
int type;
int x, y, w;
};
const int MAXN = 2e5;
int d[MAXN + 5];
vi g[MAXN + 5];
int tin[MAXN + 5], tout[MAXN + 5];
int timeAdd[MAXN + 5];
int timeDfs = 0;
void dfs(int u) {
tin[u] = ++timeDfs;
for(int &v : g[u]) dfs(v);
tout[u] = timeDfs;
}
void solve()
{
int q; cin >> q;
vector<Query> queries(q);
int n = 1;
d[1] = 0;
timeAdd[1] = -1;
{
int cur = 1;
for(int i = 0; i < q; i++) {
auto &it = queries[i];
string s; cin >> s;
if(s == "Add") it.type = 0;
else it.type = 1;
cin >> it.x;
if(it.type == 0) {
cin >> it.w;
it.y = ++cur;
n++;
timeAdd[it.y] = i;
g[it.x].push_back(it.y);
d[it.y] = d[it.x] ^ it.w;
}
else {
cin >> it.y;
}
// cout << it.x << ' ' << it.y << ' ' << it.w << '\n';
}
}
dfs(1);
for(int i = 1; i <= n; i++) trie.add(d[i], {tin[i], timeAdd[i]});
trie.init();
for(int i = 0; i < q; i++) {
auto it = queries[i];
if(it.type == 0) continue;
cout << (d[it.x] ^ trie.query(d[it.x], tin[it.y], tout[it.y], i)) << '\n';
}
}
signed main()
{
setIO();
int t = 1;
// cin >> t;
while (t--)
solve();
}
Compilation message (stderr)
klasika.cpp: In function 'void setIO(std::string)':
klasika.cpp:26:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
26 | freopen((name + ".INP").c_str(), "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
klasika.cpp:27:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
27 | freopen((name + ".OUT").c_str(), "w", stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |