Problem p02268 (C++)

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

template <const int U = 1 << 30> class vEB {

  struct node {
    int min, max;
    node *summary, **cluster;
    node() : min(U), max(-1), summary(nullptr), cluster(nullptr) {}
  } *root;

  int cnt;

private:
  int downsqrt(int ub) const { return ub >> 1; }

  int upsqrt(int ub) { return (ub >> 1) + (ub & 1); }

  int high(int x, int ub) const { return x >> ub; }

  int low(int x, int ub) const { return x & ((1 << ub) - 1); }

  int index(int x, int y, int ub) const { return (x << downsqrt(ub)) + y; }

  int minimum(node *v) const { return v ? v->min : U; }

  int maximum(node *v) const { return v ? v->max : -1; }

  bool member(node *v, int x, int ub) const {
    if (!v)
      return false;
    if (v->min == x || v->max == x)
      return true;
    if (!v->cluster)
      return false;
    return member(v->cluster[high(x, ub)], low(x, ub), downsqrt(ub));
  }

  node *new_node(int ub) {
    node *v = new node();
    if (ub > 1) {
      int sz = 1 << upsqrt(ub);
      v->cluster = new node *[sz];
      for (int i = 0; i < sz; i++) {
        v->cluster[i] = nullptr;
      }
    }
    return v;
  }

  node *empty_insert(node *v, int x, int ub) {
    if (!v)
      v = new_node(ub);
    v->min = v->max = x;
    return v;
  }

  node *insert(node *v, int x, int ub) {
    if (!v)
      v = new_node(ub);
    if (v->min == U) {
      empty_insert(v, x, ub);
      return v;
    }
    if (x < v->min)
      swap(x, v->min);
    if (ub > 1) {
      if (minimum(v->cluster[high(x, ub)]) == U) {
        v->summary = insert(v->summary, high(x, ub), upsqrt(ub));
        v->cluster[high(x, ub)] =
            empty_insert(v->cluster[high(x, ub)], low(x, ub), downsqrt(ub));
      } else {
        v->cluster[high(x, ub)] =
            insert(v->cluster[high(x, ub)], low(x, ub), downsqrt(ub));
      }
    }
    if (x > v->max)
      v->max = x;
    return v;
  }

  node *erase(node *v, int x, int ub) {
    if (v->min == v->max) {
      v->min = U;
      v->max = -1;
      return nullptr;
    }
    if (ub <= 1) {
      v->max = v->min = (x == 0);
      return v;
    }
    if (x == v->min) {
      int first_cluster = minimum(v->summary);
      v->min = x = index(first_cluster, minimum(v->cluster[first_cluster]), ub);
    }
    v->cluster[high(x, ub)] =
        erase(v->cluster[high(x, ub)], low(x, ub), downsqrt(ub));
    if (minimum(v->cluster[high(x, ub)]) == U) {
      v->summary = erase(v->summary, high(x, ub), upsqrt(ub));
      if (x == v->max) {
        int summary_max = maximum(v->summary);
        if (summary_max == -1) {
          v->max = v->min;
        } else {
          v->max = index(summary_max, maximum(v->cluster[summary_max]), ub);
        }
      }
    } else if (x == v->max) {
      v->max = index(high(x, ub), maximum(v->cluster[high(x, ub)]), ub);
    }
    return v;
  }

  int successor(node *v, int x, int ub) const {
    if (ub <= 1) {
      if (x == 0 && v->max == 1)
        return 1;
      return U;
    }
    if (v->min != U && x < v->min)
      return v->min;
    int max_low = maximum(v->cluster[high(x, ub)]);
    if (max_low != -1 && low(x, ub) < max_low) {
      return index(high(x, ub),
                   successor(v->cluster[high(x, ub)], low(x, ub), downsqrt(ub)),
                   ub);
    }
    int succ_cluster = successor(v->summary, high(x, ub), upsqrt(ub));
    if (succ_cluster == U)
      return U;
    return index(succ_cluster, minimum(v->cluster[succ_cluster]), ub);
  }

  int predecessor(node *v, int x, int ub) const {
    if (ub <= 1) {
      if (x == 1 && v->min == 0)
        return 0;
      return -1;
    }
    if (v->max != -1 && x > v->max)
      return v->max;
    int min_low = minimum(v->cluster[high(x, ub)]);
    if (min_low != U && low(x, ub) > min_low) {
      return index(
          high(x, ub),
          predecessor(v->cluster[high(x, ub)], low(x, ub), downsqrt(ub)), ub);
    }
    int pred_cluster = predecessor(v->summary, high(x, ub), upsqrt(ub));
    if (pred_cluster == -1) {
      if (v->min != -1 && x > v->min)
        return v->min;
      return -1;
    }
    return index(pred_cluster, maximum(v->cluster[pred_cluster]), ub);
  }

public:
  vEB() : root(nullptr), cnt(0) {}

  int size() const { return cnt; }

  bool member(int x) const { return member(root, x, __builtin_ctz(U)); }

  int minimum() const { return minimum(root); }

  int maximum() const { return maximum(root); }

  void insert(int x) {
    if (!member(x))
      root = insert(root, x, __builtin_ctz(U)), cnt++;
  }

  void erase(int x) {
    if (member(x))
      root = erase(root, x, __builtin_ctz(U)), cnt--;
  }

  int successor(int x) const { return successor(root, x, __builtin_ctz(U)); }

  int predecessor(int x) const {
    return predecessor(root, x, __builtin_ctz(U));
  }
};

int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  int n, q;
  cin >> n;
  vEB<> veb;
  for (int i = 0; i < n; i++) {
    int si;
    cin >> si;
    veb.insert(si);
  }
  int res = 0;
  cin >> q;
  for (int j = 0; j < q; j++) {
    int ti;
    cin >> ti;
    res += veb.member(ti);
  }
  cout << res << endl;
  return 0;
}


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

template <const int U = 1 << 30> class vEB {

  struct node {
    int min, max;
    node *summary, **cluster;
    node() : min(U), max(-1), summary(nullptr), cluster(nullptr) {}
  } *root;

  int cnt;

private:
  int downsqrt(int ub) const { return ub >> 1; }

  int upsqrt(int ub) { return (ub >> 1) + (ub & 1); }

  int high(int x, int ub) const { return x >> downsqrt(ub); }

  int low(int x, int ub) const { return x & ((1 << downsqrt(ub)) - 1); }

  int index(int x, int y, int ub) const { return (x << downsqrt(ub)) + y; }

  int minimum(node *v) const { return v ? v->min : U; }

  int maximum(node *v) const { return v ? v->max : -1; }

  bool member(node *v, int x, int ub) const {
    if (!v)
      return false;
    if (v->min == x || v->max == x)
      return true;
    if (!v->cluster)
      return false;
    return member(v->cluster[high(x, ub)], low(x, ub), downsqrt(ub));
  }

  node *new_node(int ub) {
    node *v = new node();
    if (ub > 1) {
      int sz = 1 << upsqrt(ub);
      v->cluster = new node *[sz];
      for (int i = 0; i < sz; i++) {
        v->cluster[i] = nullptr;
      }
    }
    return v;
  }

  node *empty_insert(node *v, int x, int ub) {
    if (!v)
      v = new_node(ub);
    v->min = v->max = x;
    return v;
  }

  node *insert(node *v, int x, int ub) {
    if (!v)
      v = new_node(ub);
    if (v->min == U) {
      empty_insert(v, x, ub);
      return v;
    }
    if (x < v->min)
      swap(x, v->min);
    if (ub > 1) {
      if (minimum(v->cluster[high(x, ub)]) == U) {
        v->summary = insert(v->summary, high(x, ub), upsqrt(ub));
        v->cluster[high(x, ub)] =
            empty_insert(v->cluster[high(x, ub)], low(x, ub), downsqrt(ub));
      } else {
        v->cluster[high(x, ub)] =
            insert(v->cluster[high(x, ub)], low(x, ub), downsqrt(ub));
      }
    }
    if (x > v->max)
      v->max = x;
    return v;
  }

  node *erase(node *v, int x, int ub) {
    if (v->min == v->max) {
      v->min = U;
      v->max = -1;
      return nullptr;
    }
    if (ub <= 1) {
      v->max = v->min = (x == 0);
      return v;
    }
    if (x == v->min) {
      int first_cluster = minimum(v->summary);
      v->min = x = index(first_cluster, minimum(v->cluster[first_cluster]), ub);
    }
    v->cluster[high(x, ub)] =
        erase(v->cluster[high(x, ub)], low(x, ub), downsqrt(ub));
    if (minimum(v->cluster[high(x, ub)]) == U) {
      v->summary = erase(v->summary, high(x, ub), upsqrt(ub));
      if (x == v->max) {
        int summary_max = maximum(v->summary);
        if (summary_max == -1) {
          v->max = v->min;
        } else {
          v->max = index(summary_max, maximum(v->cluster[summary_max]), ub);
        }
      }
    } else if (x == v->max) {
      v->max = index(high(x, ub), maximum(v->cluster[high(x, ub)]), ub);
    }
    return v;
  }

  int successor(node *v, int x, int ub) const {
    if (ub <= 1) {
      if (x == 0 && v->max == 1)
        return 1;
      return U;
    }
    if (v->min != U && x < v->min)
      return v->min;
    int max_low = maximum(v->cluster[high(x, ub)]);
    if (max_low != -1 && low(x, ub) < max_low) {
      return index(high(x, ub),
                   successor(v->cluster[high(x, ub)], low(x, ub), downsqrt(ub)),
                   ub);
    }
    int succ_cluster = successor(v->summary, high(x, ub), upsqrt(ub));
    if (succ_cluster == U)
      return U;
    return index(succ_cluster, minimum(v->cluster[succ_cluster]), ub);
  }

  int predecessor(node *v, int x, int ub) const {
    if (ub <= 1) {
      if (x == 1 && v->min == 0)
        return 0;
      return -1;
    }
    if (v->max != -1 && x > v->max)
      return v->max;
    int min_low = minimum(v->cluster[high(x, ub)]);
    if (min_low != U && low(x, ub) > min_low) {
      return index(
          high(x, ub),
          predecessor(v->cluster[high(x, ub)], low(x, ub), downsqrt(ub)), ub);
    }
    int pred_cluster = predecessor(v->summary, high(x, ub), upsqrt(ub));
    if (pred_cluster == -1) {
      if (v->min != -1 && x > v->min)
        return v->min;
      return -1;
    }
    return index(pred_cluster, maximum(v->cluster[pred_cluster]), ub);
  }

public:
  vEB() : root(nullptr), cnt(0) {}

  int size() const { return cnt; }

  bool member(int x) const { return member(root, x, __builtin_ctz(U)); }

  int minimum() const { return minimum(root); }

  int maximum() const { return maximum(root); }

  void insert(int x) {
    if (!member(x))
      root = insert(root, x, __builtin_ctz(U)), cnt++;
  }

  void erase(int x) {
    if (member(x))
      root = erase(root, x, __builtin_ctz(U)), cnt--;
  }

  int successor(int x) const { return successor(root, x, __builtin_ctz(U)); }

  int predecessor(int x) const {
    return predecessor(root, x, __builtin_ctz(U));
  }
};

int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  int n, q;
  cin >> n;
  vEB<> veb;
  for (int i = 0; i < n; i++) {
    int si;
    cin >> si;
    veb.insert(si);
  }
  int res = 0;
  cin >> q;
  for (int j = 0; j < q; j++) {
    int ti;
    cin >> ti;
    res += veb.member(ti);
  }
  cout << res << endl;
  return 0;
}