제출 #1349319

#제출 시각아이디문제언어결과실행 시간메모리
1349319Hamed5001Klasika (COCI20_klasika)C++20
0 / 110
785 ms118568 KiB
#include <bits/stdc++.h>

using namespace std;

template<typename T> void umax(T &a, const T b) { a = max(a, b); }
template<typename T> void umin(T &a, const T b) { a = min(a, b); }

constexpr int MAXN = 3e5 + 10;
int head[MAXN], to[MAXN*2], nxt[MAXN*2], w[MAXN*2], ne;
int in[MAXN], out[MAXN], W[MAXN], TIME;
void add_edge(int u, int v, int weight) {
  to[ne] = v;
  w[ne] = weight;
  nxt[ne] = head[u];
  head[u] = ne++;
}

struct SegmentTree {
#define L   (node<<1)
#define R   (node<<1|1)
#define MID (l+r>>1)
  int N;
  vector<int64_t> seg;
  SegmentTree(int N) : N(N) { seg.resize(N*4); }
};


void dfs(int v, int p=-1, int weight = 0) {
  in[v] = TIME++;
  W[v] = weight;
  for (int e = head[v], u; ~e; e = nxt[e]) {
    u = to[e]; if (u == p) continue;
    dfs(u, v, weight^w[e]);
  }
  out[v] = TIME;
}

struct Trie {
  struct TrieNode {
    TrieNode *p0 = nullptr, *p1 = nullptr;
    set<int> indices;
    void add_idx(int idx) { indices.insert(idx); }
  };
  TrieNode *head;
  Trie() { head = new TrieNode(); }
  void insert(int num, int idx) {
    TrieNode *curr = head;
    for (int i = 30; ~i; --i) {
      curr->add_idx(idx);
      if ((num>>i)&1) {
        if (!curr->p1) curr->p1 = new TrieNode();
        curr = curr->p1;
      } else {
        if (!curr->p0) curr->p0 = new TrieNode();
        curr = curr->p0;
      }
    }
    curr->add_idx(idx);
  }
  bool check(int num, int len, int left, int right) {
    TrieNode *curr = head;
    for (int i = 30; ~i && len; --i, --len) {
      if ((num>>i)&1) {
        if (!curr->p1) return false;
        curr = curr->p1;
      } else {
        if (!curr->p0) return false;
        curr = curr->p0;
      }
    }
    auto it = curr->indices.lower_bound(left);
    if (it == curr->indices.end()) return false;
    return left <= *it && *it <= right;
  }
};


int main() {
  cin.tie()->sync_with_stdio(false);
  memset(head, -1, sizeof head);
  int Q; cin >> Q;
  int N = 1;
  vector<array<int, 3>> queries(Q);
  for (auto &q : queries) {
    string s; cin >> s;
    if (s == "Add") {
      int x, y; cin >> x >> y;
      add_edge(--x, N, y);
      add_edge(N, x, y);
      q = {1, x, N};
      N++;
    } else {
      int a, b; cin >> a >> b;
      q = {2, --a, --b};
    }
  }
  Trie trie;
  dfs(0);
  for (auto q : queries) {
    if (q[0] == 1) {
      trie.insert(W[q[2]], in[q[2]]);       
    } else {
      int ans = W[q[1]];
      int target = 0;
      for (int i = 30, j = 1; ~i; --i, ++j) {
        int test = target;
        if (!((ans>>i)&1)) test |= (1<<i);
        if (trie.check(test, j, in[q[2]], out[q[2]]-1)) target = test;
        else target = test ^ (1<<i);
      }
      cout << (ans^target) << endl;
    }
  }
  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...