Problem p03422 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

mt19937 rnd;

template <typename T> struct TreapArray {
  struct Node {
    T val, sum;
    int pri, cnt;
    Node *lch, *rch;
    Node(T v) : val(v), pri(rnd()), cnt(1), sum(v) { lch = rch = nullptr; }
  };

  Node *node;

  TreapArray(Node *n = nullptr) { node = n; }
  TreapArray(T v) { node = new Node(v); }
  void initialize(T v) { node = new Node(v); }

  int count(Node *t) { return !t ? 0 : t->cnt; }
  T sum(Node *t) { return !t ? 0 : t->sum; }
  int count() { return count(node); }
  T sum() { return sum(node); }

  Node *update(Node *t) {
    t->cnt = count(t->lch) + count(t->rch) + 1;
    t->sum = sum(t->lch) + sum(t->rch) + t->val;
    return t;
  }

  Node *merge(Node *l, Node *r) {
    if (!l || !r)
      return !l ? r : l;
    if (l->pri > r->pri) {
      l->rch = merge(l->rch, r);
      return update(l);
    } else {
      r->lch = merge(l, r->lch);
      return update(r);
    }
  }

  pair<Node *, Node *> split(Node *t, int k) {
    if (!t)
      return make_pair(nullptr, nullptr);
    if (k <= count(t->lch)) {
      auto s = split(t->lch, k);
      t->lch = s.second;
      return {s.first, update(t)};
    } else {
      auto s = split(t->rch, k - count(t->lch) - 1);
      t->rch = s.first;
      return {update(t), s.second};
    }
  }
  pair<TreapArray *, TreapArray *> split(int k) {
    auto p = split(node, k);
    node = p.first;
    auto t2 = new TreapArray(p.second);
    return make_pair(this, t2);
  }

  void insert(int k, T v) {
    auto s = split(node, k);
    auto n = new Node(v);
    node = merge(s.first, n);
    node = merge(node, s.second);
  }

  void erase(int k) {
    auto s1 = split(node, k - 1);
    auto s2 = split(s1.second, 1);
    node = merge(s1.first, s2.second);
  }

  T kth_element(Node *t, int k) {
    if (k == count(t->lch)) {
      return t->val;
    } else if (k < count(t->lch)) {
      return kth_element(t->lch, k);
    } else {
      return kth_element(t->rch, k - count(t->lch) - 1);
    }
  }
  T kth_element(int k) { return kth_element(node, k); }
};

int grundy1(int A, int K) {
  while (true) {
    if (A < K)
      return 0;
    if (A % K == 0)
      return A / K;
    A -= A / K + 1;
  }
}

int grundy2(int A, int K) {
  TreapArray<int> treap(0);
  int pos = 0, sz = 1;
  for (int i = 1; i * K <= A; i++) {
    pos = (pos + K - 1) % i + 1;
    treap.insert(pos, i);
    sz++;
  }
  pos = (pos + A % K) % sz;
  return treap.kth_element(pos);
}

int main() {
  int N, G = 0;
  cin >> N;
  for (int i = 0; i < N; i++) {
    int A, K;
    cin >> A >> K;
    if (K < 1e4) {
      G ^= grundy1(A, K);
    } else {
      G ^= grundy2(A, K);
    }
  }
  cout << (G ? "Takahashi" : "Aoki") << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

mt19937 rnd;

template <typename T> struct TreapArray {
  struct Node {
    T val, sum;
    int pri, cnt;
    Node *lch, *rch;
    Node(T v) : val(v), pri(rnd()), cnt(1), sum(v) { lch = rch = nullptr; }
  };

  Node *node;

  TreapArray(Node *n = nullptr) { node = n; }
  TreapArray(T v) { node = new Node(v); }
  void initialize(T v) { node = new Node(v); }

  int count(Node *t) { return !t ? 0 : t->cnt; }
  T sum(Node *t) { return !t ? 0 : t->sum; }
  int count() { return count(node); }
  T sum() { return sum(node); }

  Node *update(Node *t) {
    t->cnt = count(t->lch) + count(t->rch) + 1;
    t->sum = sum(t->lch) + sum(t->rch) + t->val;
    return t;
  }

  Node *merge(Node *l, Node *r) {
    if (!l || !r)
      return !l ? r : l;
    if (l->pri > r->pri) {
      l->rch = merge(l->rch, r);
      return update(l);
    } else {
      r->lch = merge(l, r->lch);
      return update(r);
    }
  }

  pair<Node *, Node *> split(Node *t, int k) {
    if (!t)
      return make_pair(nullptr, nullptr);
    if (k <= count(t->lch)) {
      auto s = split(t->lch, k);
      t->lch = s.second;
      return {s.first, update(t)};
    } else {
      auto s = split(t->rch, k - count(t->lch) - 1);
      t->rch = s.first;
      return {update(t), s.second};
    }
  }
  pair<TreapArray *, TreapArray *> split(int k) {
    auto p = split(node, k);
    node = p.first;
    auto t2 = new TreapArray(p.second);
    return make_pair(this, t2);
  }

  void insert(int k, T v) {
    auto s = split(node, k);
    auto n = new Node(v);
    node = merge(s.first, n);
    node = merge(node, s.second);
  }

  void erase(int k) {
    auto s1 = split(node, k - 1);
    auto s2 = split(s1.second, 1);
    node = merge(s1.first, s2.second);
  }

  T kth_element(Node *t, int k) {
    if (k == count(t->lch)) {
      return t->val;
    } else if (k < count(t->lch)) {
      return kth_element(t->lch, k);
    } else {
      return kth_element(t->rch, k - count(t->lch) - 1);
    }
  }
  T kth_element(int k) { return kth_element(node, k); }
};

int grundy1(int A, int K) {
  while (true) {
    if (A < K)
      return 0;
    if (A % K == 0)
      return A / K;
    A -= A / K + 1;
  }
}

int grundy2(int A, int K) {
  TreapArray<int> treap(0);
  int pos = 0, sz = 1;
  for (int i = 1; i * K <= A; i++) {
    pos = (pos + K - 1) % i + 1;
    treap.insert(pos, i);
    sz++;
  }
  pos = (pos + A % K) % sz;
  return treap.kth_element(pos);
}

int main() {
  int N, G = 0;
  cin >> N;
  for (int i = 0; i < N; i++) {
    int A, K;
    cin >> A >> K;
    if (K < 1e5) {
      G ^= grundy1(A, K);
    } else {
      G ^= grundy2(A, K);
    }
  }
  cout << (G ? "Takahashi" : "Aoki") << endl;
  return 0;
}