/*
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 SegmentTree {
int n;
vector<int> a;
vector<int> st;
SegmentTree(int _n) {
n = _n;
a.assign(n + 1, 0);
st.assign(4 * n + 5, INF);
}
void build(int id, int l, int r) {
if (l == r) {
st[id] = a[l];
return;
}
int mid = (l + r) >> 1;
build(id * 2, l, mid);
build(id * 2 + 1, mid + 1, r);
st[id] = min(st[id * 2], st[id * 2 + 1]);
}
void update(int id, int l, int r, int i, int val) {
if (i < l || i > r) return;
if (l == r) {
st[id] = val;
return;
}
int mid = (l + r) >> 1;
update(id * 2, l, mid, i, val);
update(id * 2 + 1, mid + 1, r, i, val);
st[id] = min(st[id * 2], st[id * 2 + 1]);
}
int get(int id, int l, int r, int u, int v) {
if (v < l || u > r) return INF;
if (u <= l && r <= v) return st[id];
int mid = (l + r) >> 1;
int left = get(id * 2, l, mid, u, v);
int right = get(id * 2 + 1, mid + 1, r, u, v);
return min(left, right);
}
};
struct Trie {
struct Node {
int cnt = 0;
vector<pii> v;
vi v_nw;
SegmentTree *seg = nullptr;
int n;
int child[2] = {-1, -1};
void init() {
sort(v.begin(), v.end());
n = (int)v.size();
seg = new SegmentTree(n);
for (int i = 0; i < n; ++i) {
seg->a[i + 1] = v[i].s;
v_nw.push_back(v[i].f);
}
seg->build(1, 1, n);
}
int query_min(int l, int r) {
if (n == 0) return INF;
return seg->get(1, 1, n, l + 1, r + 1);
}
bool exist(int time_in, int time_out, int time_query) {
if (v_nw.empty()) return false;
auto it1 = lower_bound(v_nw.begin(), v_nw.end(), time_in);
auto it2 = upper_bound(v_nw.begin(), v_nw.end(), time_out);
if (it1 == v_nw.end()) return false;
int id1 = it1 - v_nw.begin(), id2 = it2 - v_nw.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();
}
컴파일 시 표준 에러 (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... |