Submission #1346036

#TimeUsernameProblemLanguageResultExecution timeMemory
1346036abdoKlasika (COCI20_klasika)C++20
33 / 110
268 ms589824 KiB
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <cmath>
#include <deque>
#include <iomanip>
#include <stack>
#include <queue>
#include <cstring>
#include <array>
#include <random>
#include <chrono>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define endl '\n'
#define yes cout << "YES\n";
#define no cout << "NO\n";
#define ll int
#define sz(x) (int)x.size()
#define EO(x) (x & 1 ? "ODD" : "EVEN")
#define YN(x) (x ? "YES" : "NO")
#define watch(x) cout << #x << " = " << x << endl

void bad_man()
{
    ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    // freopen("input.txt", "r", stdin);
}
struct Node
{
    Node *nxt[2];
    int cnt;
    int mn_time;
    Node()
    {
        cnt = 0;
        mn_time = 1e9;
        memset(nxt, 0, sizeof nxt);
    }
};

struct Trie
{
    Node *root;
    vector<pair<int, int>> arr;
    Trie()
    {
        arr.clear();
        root = new Node;
    }

    ~Trie()
    {
        delete root;
    }

    void insert(int x, int time)
    {
        arr.push_back({x, time});
        Node *cur = root;
        cur->mn_time = min(cur->mn_time, time);
        for (int bit = 31; ~bit; --bit)
        {
            int b = bool(x & (1ll << bit));
            if (!cur->nxt[b])
                cur->nxt[b] = new Node();
            cur = cur->nxt[b];
            cur->cnt++;
            cur->mn_time = min(cur->mn_time, time);
        }
    }

    // max XOR with x
    int max_xor(int x, int time)
    {
        Node *cur = root;
        if (cur->mn_time > time)
            return x;
        for (int bit = 31; ~bit; --bit)
        {
            int b = bool(x & (1ll << bit));
            if (cur->nxt[!b] && cur->nxt[!b]->mn_time <= time)
            {
                x ^= (!b << bit);
                cur = cur->nxt[!b];
            }
            else
            {
                x ^= (b << bit);
                cur = cur->nxt[b];
            }
        }
        return x;
    }
};

ll const N = 2e5 + 5;
struct edge
{
    int to, w, time;
};
vector<edge> adj[N];
vector<ll> ans;
vector<tuple<int, int, int>> que[N];
ll pref[N], dep[N], par[N][20];
void dfs(int u, int p)
{
    dep[u] = dep[p] + 1;
    par[u][0] = p;
    for (int i = 1; i < 20; ++i)
        par[u][i] = par[par[u][i - 1]][i - 1];
    for (auto [v, w, time] : adj[u])
    {
        if (v == p)
            continue;
        pref[v] = pref[u] ^ w;
        dfs(v, u);
    }
}
int lca(int u, int v)
{
    if (dep[u] < dep[v])
        swap(u, v);
    for (int i = 19; i >= 0; --i)
    {
        if (dep[par[u][i]] >= dep[v])
            u = par[u][i];
    }
    if (u == v)
        return u;
    for (int i = 19; i >= 0; --i)
    {
        if (par[u][i] != par[v][i])
        {
            u = par[u][i];
            v = par[v][i];
        }
    }
    return par[u][0];
}
Trie trie[N];
void dfs2(int u, int p)
{
    for (auto [v, w, time] : adj[u])
    {
        if (v == p)
            continue;
        trie[v].insert(pref[v], time);
        dfs2(v, u);
        if (trie[u].arr.size() < trie[v].arr.size())
            swap(trie[u], trie[v]);
        for (auto &[x, t] : trie[v].arr)
            trie[u].insert(x, t);
    }
    for (auto &[u2, time, idx] : que[u])
    {
        ans[idx] = trie[u].max_xor(pref[u2], time);
    }
}
void solve()
{
    ll q;
    cin >> q;
    ll cur = 2;
    for (int i = 0; i < q; ++i)
    {
        string t;
        cin >> t;
        if (t[0] == 'A')
        {
            int u, v, w;
            cin >> u >> w;
            v = cur++;
            adj[u].push_back({v, w, i});
            adj[v].push_back({u, w, i});
        }
        else
        {
            int u, v;
            cin >> u >> v;
            que[v].emplace_back(u, i, ans.size());
            ans.push_back(0);
        }
    }
    dfs(1, 0);
    trie[1].insert(pref[1], 0);
    dfs2(1, 0);
    for (auto &i : ans)
        cout << i << endl;
    for (int i = 0; i < cur; ++i)
        trie[i].arr.clear(), trie[i].root = new Node;
}

int main()
{
    bad_man();
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }
    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...