Problem p02268 (C++) — buggy submission, verdict: 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) {}
    ~node() {
      if (summary)
        delete summary;
      if (cluster)
        delete[] cluster;
    }
  } *root;

  int cnt;

private:
  int downsqrt(int u) const {
    assert(u != 0 && (u & (u - 1)) == 0 && u > 2);
    return 1 << (__builtin_ctz(u) >> 1);
  }

  int upsqrt(int u) {
    assert(u != 0 && (u & (u - 1)) == 0 && u > 2);
    int ctz = __builtin_ctz(u);
    return 1 << ((ctz >> 1) + (ctz & 1));
  }

  int high(int x, int u) const { return x / downsqrt(u); }

  int low(int x, int u) const { return x % downsqrt(u); }

  int index(int x, int y, int u) const { return x * downsqrt(u) + 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 u) 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, u)], low(x, u), downsqrt(u));
  }

  node *new_node(int u) {
    node *v = new node();
    if (u > 2) {
      int sz = upsqrt(u);
      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 u) {
    if (!v)
      v = new_node(u);
    v->min = v->max = x;
    return v;
  }

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

  node *erase(node *v, int x, int u) {
    if (v->min == v->max) {
      v->min = U;
      v->max = -1;
      delete v;
      return nullptr;
    }
    if (u <= 2) {
      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]), u);
    }
    v->cluster[high(x, u)] =
        erase(v->cluster[high(x, u)], low(x, u), downsqrt(u));
    if (minimum(v->cluster[high(x, u)]) == U) {
      v->summary = erase(v->summary, high(x, u), upsqrt(u));
      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]), u);
        }
      }
    } else if (x == v->max) {
      v->max = index(high(x, u), maximum(v->cluster[high(x, u)]), u);
    }
    return v;
  }

  int successor(node *v, int x, int u) const {
    if (u <= 2) {
      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, u)]);
    if (max_low != -1 && low(x, u) < max_low) {
      return index(high(x, u),
                   successor(v->cluster[high(x, u)], low(x, u), downsqrt(u)),
                   u);
    }
    int succ_cluster = successor(v->summary, high(x, u), upsqrt(u));
    if (succ_cluster == U)
      return U;
    return index(succ_cluster, minimum(v->cluster[succ_cluster]), u);
  }

  int predecessor(node *v, int x, int u) const {
    if (u <= 2) {
      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, u)]);
    if (min_low != U && low(x, u) > min_low) {
      return index(high(x, u),
                   predecessor(v->cluster[high(x, u)], low(x, u), downsqrt(u)),
                   u);
    }
    int pred_cluster = predecessor(v->summary, high(x, u), upsqrt(u));
    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]), u);
  }

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

  ~vEB() {
    if (root)
      delete root;
  }

  int size() const { return cnt; }

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

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

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

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

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

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

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

int main() {
  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;
}


Error: 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) {}
    ~node() {
      if (summary)
        delete summary;
      if (cluster)
        delete[] cluster;
    }
  } *root;

  int cnt;

private:
  int downsqrt(int u) const {
    assert(u != 0 && (u & (u - 1)) == 0 && u > 2);
    return 1 << (__builtin_ctz(u) >> 1);
  }

  int upsqrt(int u) const {
    assert(u != 0 && (u & (u - 1)) == 0 && u > 2);
    int ctz = __builtin_ctz(u);
    return 1 << ((ctz >> 1) + (ctz & 1));
  }

  int high(int x, int u) const { return x / downsqrt(u); }

  int low(int x, int u) const { return x % downsqrt(u); }

  int index(int x, int y, int u) const { return x * downsqrt(u) + 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 u) 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, u)], low(x, u), downsqrt(u));
  }

  node *new_node(int u) {
    node *v = new node();
    if (u > 2) {
      int sz = upsqrt(u);
      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 u) {
    if (!v)
      v = new_node(u);
    v->min = v->max = x;
    return v;
  }

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

  node *erase(node *v, int x, int u) {
    if (v->min == v->max) {
      v->min = U;
      v->max = -1;
      delete v;
      return nullptr;
    }
    if (u <= 2) {
      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]), u);
    }
    v->cluster[high(x, u)] =
        erase(v->cluster[high(x, u)], low(x, u), downsqrt(u));
    if (minimum(v->cluster[high(x, u)]) == U) {
      v->summary = erase(v->summary, high(x, u), downsqrt(u));
      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]), u);
        }
      }
    } else if (x == v->max) {
      v->max = index(high(x, u), maximum(v->cluster[high(x, u)]), u);
    }
    return v;
  }

  int successor(node *v, int x, int u) const {
    if (u <= 2) {
      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, u)]);
    if (max_low != -1 && low(x, u) < max_low) {
      return index(high(x, u),
                   successor(v->cluster[high(x, u)], low(x, u), downsqrt(u)),
                   u);
    }
    int succ_cluster = successor(v->summary, high(x, u), downsqrt(u));
    if (succ_cluster == U)
      return U;
    return index(succ_cluster, minimum(v->cluster[succ_cluster]), u);
  }

  int predecessor(node *v, int x, int u) const {
    if (u <= 2) {
      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, u)]);
    if (min_low != U && low(x, u) > min_low) {
      return index(high(x, u),
                   predecessor(v->cluster[high(x, u)], low(x, u), downsqrt(u)),
                   u);
    }
    int pred_cluster = predecessor(v->summary, high(x, u), downsqrt(u));
    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]), u);
  }

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

  ~vEB() {
    if (root)
      delete root;
  }

  int size() const { return cnt; }

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

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

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

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

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

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

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

int main() {
  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;
}