Submission #1347981

#TimeUsernameProblemLanguageResultExecution timeMemory
1347981vladmart09Klasika (COCI20_klasika)C++20
0 / 110
500 ms498304 KiB

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <random>
#include <queue>
#include <numeric>
#include <array>
#include <iomanip>
#include <stack>
#include <chrono>
#include <climits>

using namespace std;

using ll = int;
using ld = long double;
using vi = vector<ll>;
using vii = vector<vi>;
using viii = vector<vii>;
using pi = pair<ll, ll>;
using vpi = vector<pi>;
using vb = vector<bool>;
using vs = vector<string>;

#define vec vector
#define cmax(x, y) x = max({x, y})
#define cmin(x, y) x = min({x, y})
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

const ll N = 2e5 + 5, MOD = 1e9 + 7, INF = (ll)1e18, K = 20;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct Query {
	string op;
	ll a, b;
};

struct Trie {
	struct node {
		node* one, *zero;

		node() : one(0), zero(0) {}
	};

	node* root;

	Trie() : root(new node()) {}

	void add(ll x) {
		node* cur = root;

		for (ll i = 30; i >= 0; i--) {
			if (x >> i & 1) {
				if (!cur->one) cur->one = new node();

				cur = cur->one;
			}
			else {
				if (!cur->zero) cur->zero = new node();

				cur = cur->zero;
			}
		}
	}

	ll best(ll x) {
		if (!root->one && !root->zero) return x;

		node* cur = root;
		ll y = 0;

		for (ll i = 30; i >= 0; i--) {
			if (!cur->zero || (cur->one && !(x >> i & 1))) {
				cur = cur->one;
				y |= (1ll << i);
			}
			else {
				cur = cur->zero;
			}
		}

		return y ^ x;
	}
};

struct Seg {
	vector<Trie> seg;

	Seg(ll n) {
		seg.resize(4 * n);
	}

	void update(ll t, ll tl, ll tr, ll i, ll x) {
		seg[t].add(x);

		if (tl == tr) return;

		ll tm = tl + (tr - tl) / 2;

		if (i <= tm) update(t * 2, tl, tm, i, x);
		else update(t * 2 + 1, tm + 1, tr, i, x);
	}

	ll get(ll t, ll tl, ll tr, ll l, ll r, ll x) {
		if (tl > r || tr < l) return 0;

		if (l <= tl && tr <= r) {
			return seg[t].best(x);
		}

		ll tm = tl + (tr - tl) / 2;

		ll res1 = get(t * 2, tl, tm, l, r, x);
		ll res2 = get(t * 2 + 1, tm + 1, tr, l, r, x);

		return max(res1, res2);
	}
};

vi g[N];
ll tin[N], tout[N], timer = 1, val[N];

void dfs(ll v) {
	tin[v] = timer++;

	for (auto& x : g[v]) {
		dfs(x);
	}
	
	tout[v] = timer - 1;
}

void solve() {
	ll q; cin >> q;

	vector<Query> qu(q);

	ll sz = 1;
	for (ll i = 0; i < q; i++) {
		cin >> qu[i].op >> qu[i].a >> qu[i].b;

		if (qu[i].op == "Add") {
			sz++;
			g[qu[i].a].push_back(sz);
		}
	}

	dfs(1);

	Seg seg(sz);

	ll n = sz;
	sz = 1;

	for (ll i = 0; i < q; i++) {
		auto [op, a, b] = qu[i];

		if (op == "Add") {
			sz++;
			val[sz] = val[a] ^ b;
			seg.update(1, 1, n, tin[sz], val[sz]);
		}
		else {
			cout << seg.get(1, 1, n, tin[b], tout[b], val[a]) << '\n';
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	long long tt = 1;
	//cin >> tt;

	while (tt--) {
		solve();
		cout << '\n';
	}

	return 0;
}

/*




























Какие темы повторить:
1) мст
2) 2сат
3) точки артикуляции
4) ксор базис
5) эйлеровый цикл, путь
6) кмп
7) конвекс хулл
8) вафельное дерево
9) суфиксный массив
10) суффиксный автомат
11) ним

*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...