Problem p02457 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <bits/stdc++.h>

#define ALL(a) (a).begin(), (a).end()
#define ll long long

// van Emde Boas trees 要素は正の整数
class VEBtree;

class VEBtreeNode {
  using Number = unsigned long long;
  friend VEBtree;
  const Number K;                                // universe = 2 ^ K
  const Number uppersqrt = (1 << ((K + 1) / 2)); // sqrt(ceil(universe/2))
  const Number lowersqrt = (1 << (K / 2));       // sqrt(floor(universe/2))
  Number min_, max_;
  std::map<Number, VEBtreeNode> cluster;
  VEBtreeNode *summary = nullptr;

  Number high(Number x) { return x / lowersqrt; }
  Number low(Number x) { return x % lowersqrt; }
  Number index(Number x, Number y) { return x * lowersqrt + y; }

  Number min() const { return min_; }
  Number max() const { return max_; }

  bool empty() const { return max() < min(); }

  bool member(Number x) {
    if (empty())
      return false;
    if (x == min() || x == max())
      return true;
    else if (K == 1)
      return false;
    if (summary == nullptr || !summary->member(high(x)))
      return false;
    return cluster.at(high(x)).member(low(x));
  }

  Number successor(Number x) {
    if (empty())
      return x;
    if (K == 1) {
      if (x == 0 && max() == 1)
        return 1;
      else
        return x;
    }
    if (x < min())
      return min();
    if (summary == nullptr)
      return max();
    if (summary->member(high(x)) && low(x) < cluster.at(high(x)).max()) {
      Number offset = cluster.at(high(x)).successor(low(x));
      return index(high(x), offset);
    }
    Number succ_cluster = summary->successor(high(x));
    if (succ_cluster == high(x))
      return x;
    else {
      Number offset = cluster.at(succ_cluster).min();
      return index(succ_cluster, offset);
    }
  }

  Number predecessor(Number x) {
    if (empty())
      return x;
    if (K == 1) {
      if (x == 1 && min() == 0)
        return 0;
      else
        return x;
    }
    if (max() < x)
      return max();
    if (summary == nullptr)
      return min();
    if (summary->member(high(x)) && cluster.at(high(x)).min() < low(x)) {
      Number offset = cluster.at(high(x)).predecessor(low(x));
      return index(high(x), offset);
    }
    Number pred_cluster = summary->predecessor(high(x));
    if (pred_cluster == high(x)) {
      return x;
    } else {
      Number offset = cluster.at(pred_cluster).max();
      return index(pred_cluster, offset);
    }
  }

  void empty_insert(Number x) {
    min_ = x;
    max_ = x;
  }

  void insert(Number x) {
    if (empty())
      empty_insert(x);
    else {
      if (x < min())
        std::swap(x, min_);
      if (K > 1) {
        if (summary == nullptr) {
          summary = new VEBtreeNode((K + 1) / 2, high(x));
          cluster.insert({high(x), VEBtreeNode(K / 2, low(x))});
        } else if (!summary->member(high(x))) {
          summary->insert(high(x));
          cluster.insert({high(x), VEBtreeNode(K / 2, low(x))});
        } else
          cluster.at(high(x)).insert(low(x));
      }
      if (x > max()) {
        max_ = x;
      }
    }
  }

  void erase(Number x) {
    assert(!empty());
    if (min() == max()) {
      min_ = 1;
      max_ = 0;
    } else if (K == 1) {
      if (x == 0)
        min_ = 1;
      else
        min_ = 0;
      max_ = min_;
    } else {
      if (x == min()) {
        Number first_cluster = summary->min();
        x = index(first_cluster, cluster.at(first_cluster).min());
        min_ = x;
      }
      cluster.at(high(x)).erase(low(x));
      if (cluster.at(high(x)).empty()) {
        summary->erase(high(x));
        cluster.erase(high(x));
        if (x == max()) {
          if (summary->empty()) {
            max_ = min();
            delete summary;
            summary = nullptr;
          } else
            max_ = index(summary->max(), cluster.at(summary->max()).max());
        }
      } else if (x == max())
        max_ = index(high(x), cluster.at(high(x)).max());
    }
  }

public:
  VEBtreeNode(Number k, Number x) : K(k), min_(x), max_(x) {}
  ~VEBtreeNode() { delete summary; }
  Number getK() const { return K; }
};

class VEBtree {
  using Number = unsigned long long;
  const Number K;
  VEBtreeNode *root;
  size_t size_;

public:
  VEBtree() : K(24), root(nullptr), size_(0) {}
  VEBtree(Number universe)
      : K(sizeof(Number) * 8 - __builtin_clzll(universe)), root(nullptr),
        size_(0) {}
  ~VEBtree() { delete root; }

  size_t size() const { return size_; }
  Number min() { return root->min(); }
  Number max() { return root->max(); }
  bool member(Number e) {
    if (size() == 0)
      return false;
    return root->member(e);
  }
  Number successor(Number e) {
    if (size() == 0)
      return e;
    return root->successor(e);
  }
  Number predecessor(Number e) {
    if (size() == 0)
      return e;
    return root->predecessor(e);
  }
  void insert(Number e) {
    if (size() == 0) {
      root = new VEBtreeNode(K, e);
      size_++;
    } else if (!member(e)) {
      root->insert(e);
      size_++;
    }
  }
  void erase(Number e) {
    if (member(e)) {
      root->erase(e);
      size_--;
    }
  }
};
/*
signed main(){
        using namespace std;
        cin.tie(0);
        ios::sync_with_stdio(false);
        int n; cin >> n;
        VEBtree t((unsigned ll)1e9);
        for(int i = 0; i < n; i++){
                int q;cin >> q;
                unsigned long long x, y, prev; cin >> x;
                switch(q){
                        case 0:
                                t.insert(x);
                                cout << t.size() << "\\n";
                                break;
                        case 1:
                                cout << t.member(x) << "\\n";
                                break;
                        case 2:
//				cerr << "erase, " << x << "\\n";
                                t.erase(x);
                                break;
                        case 3:
                                cin >> y; y++;
                                x = t.member(x) ? x : t.successor(x);
                                if(t.size() > 0 && x < y && t.member(x)){
                                        do{
                                                prev = x;
                                                cout << x << "\\n";
                                                x = t.successor(x);
                                        }while(prev != x && x < y);
                                }
                                break;
                        case 4:
                                cin >> y;
                                y = t.member(y) ? y : t.predecessor(y);
                                if(t.size() > 0){
                                        do{
                                                prev = y;
                                                cout << y << "\\n";
                                                y = t.predecessor(y);
                                        }while(prev != y && x <= y);
                                }
                                break;
                        case 5:
                                cout << t.successor(x) << "\\n";
                                break;
                        case 6:
                                cout << t.predecessor(x) << "\\n";
                                break;
                        case 7:
                                cout << t.min() << ":" << t.max() << "\\n";
                                break;
                }
        }
        {
                unsigned ll i = t.min(),prev;
                do{
                        prev = i;
                        i = t.successor(i);
                }while(i != prev);
        }


        return 0;
}
*/

signed main() {
  using namespace std;
  int n;
  scanf("%d", &n);
  VEBtree t((unsigned ll)1e9);
  for (int i = 0; i < n; i++) {
    int q;
    scanf("%d", &q);
    unsigned long long x, y, prev;
    scanf("%d", &x);
    switch (q) {
    case 0:
      t.insert(x);
      printf("%d\\n", t.size());
      break;
    case 1:
      printf("%d\\n", t.member(x));
      break;
    case 2:
      //				cerr << "erase, " << x << "\\n";
      t.erase(x);
      break;
    case 3:
      scanf("%d", &y);
      y++;
      x = t.member(x) ? x : t.successor(x);
      if (t.size() > 0 && x < y && t.member(x)) {
        do {
          prev = x;
          printf("%d\\n", x);
          x = t.successor(x);
        } while (prev != x && x < y);
      }
      break;
    case 4:
      scanf("%d", &y);
      y = t.member(y) ? y : t.predecessor(y);
      if (t.size() > 0) {
        do {
          prev = y;
          printf("%d\\n", y);
          y = t.predecessor(y);
        } while (prev != y && x <= y);
      }
      break;
    case 5:
      printf("%d\\n", t.successor(x));
      break;
    case 6:
      printf("%d\\n", t.predecessor(x));
      break;
    case 7:
      printf("%d : %d\\n", t.min(), t.max());
      break;
    }
  }
  {
    unsigned ll i = t.min(), prev;
    do {
      prev = i;
      i = t.successor(i);
    } while (i != prev);
  }
  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>

#define ALL(a) (a).begin(), (a).end()
#define ll long long

// van Emde Boas trees 要素は正の整数
class VEBtree;

class VEBtreeNode {
  using Number = unsigned long long;
  friend VEBtree;
  const Number K;
  const Number uppersqrt = (1 << ((K + 1) >> 1));
  const Number lowersqrt = (1 << (K >> 1));
  Number min_ = 1, max_ = 0;
  std::vector<VEBtreeNode> cluster;
  VEBtreeNode *summary;

  Number high(Number x) { return x / lowersqrt; }
  Number low(Number x) { return x % lowersqrt; }
  Number index(Number x, Number y) { return x * lowersqrt + y; }

  void empty_insert(Number x) {
    min_ = x;
    max_ = x;
  }
  Number min() { return min_; }
  Number max() { return max_; }

  bool member(Number x) {
    if (min() > max())
      return false;
    if (x == min() || x == max())
      return true;
    else if (K == 1)
      return false;
    assert(high(x) < cluster.size());
    return cluster[high(x)].member(low(x));
  }

  Number successor(Number x) {
    if (K == 1) {
      if (x == 0 and max() == 1)
        return 1;
      else
        return x;
    } else if (min() <= max() and x < min())
      return min();
    else {
      Number max_low = cluster[high(x)].max();
      if (cluster[high(x)].min() <= max_low and low(x) < max_low) {
        Number offset = cluster[high(x)].successor(low(x));
        return index(high(x), offset);
      }
      Number succ_cluster = summary->successor(high(x));
      if (succ_cluster == high(x))
        return x;
      else {
        Number offset = cluster[succ_cluster].min();
        return index(succ_cluster, offset);
      }
    }
  }

  Number predecessor(Number x) {
    if (K == 1) {
      if (x == 1 and min() == 0)
        return 0;
      else
        return x;
    } else if (min() <= max() and x > max()) {
      return max();
    } else {
      Number min_low = cluster[high(x)].min();
      if (min_low <= cluster[high(x)].max() and low(x) > min_low) {
        Number offset = cluster[high(x)].predecessor(low(x));
        return index(high(x), offset);
      }
      Number pred_cluster = summary->predecessor(high(x));
      if (pred_cluster == high(x)) {
        return x;
      } else {
        Number offset = cluster[pred_cluster].max();
        return index(pred_cluster, offset);
      }
    }
  }

  void insert(Number x) {
    if (min() > max())
      empty_insert(x);
    else {
      if (x < min())
        std::swap(x, min_);
      if (K > 1) {
        if (cluster[high(x)].min() > cluster[high(x)].max()) {
          summary->insert(high(x));
          cluster[high(x)].empty_insert(low(x));
        } else {
          cluster[high(x)].insert(low(x));
        }
      }
      if (x > max()) {
        max_ = x;
      }
    }
  }

  void erase(Number x) {
    if (min() == max()) {
      min_ = 1;
      max_ = 0;
    } else if (K == 1) {
      if (x == 0)
        min_ = 1;
      else
        min_ = 0;
      max_ = min_;
    } else {
      if (x == min()) {
        Number first_cluster = summary->min();
        x = index(first_cluster, cluster[first_cluster].min());
        min_ = x;
      }
      cluster[high(x)].erase(low(x));
      if (cluster[high(x)].min() > cluster[high(x)].max()) {
        summary->erase(high(x));
        if (x == max()) {
          Number summary_max = summary->max();
          if (summary_max < summary->min())
            max_ = min();
          else
            max_ = index(summary_max, cluster[summary_max].max());
        }
      } else if (x == max()) {
        max_ = index(high(x), cluster[high(x)].max());
      }
    }
  }

public:
  VEBtreeNode(const VEBtreeNode &m) : K(m.getK()) {
    if (K != 1) {
      summary = new VEBtreeNode((K + 1) >> 1);
      cluster = std::vector<VEBtreeNode>(uppersqrt, VEBtreeNode(K >> 1));
    } else {
      summary = NULL;
    }
  }

  VEBtreeNode(Number k) : K(k) {
    if (K != 1) {
      summary = new VEBtreeNode((K + 1) >> 1);
      cluster = std::vector<VEBtreeNode>(uppersqrt, VEBtreeNode(K >> 1));
    } else {
      summary = NULL;
    }
  }

  ~VEBtreeNode() = default;

  Number getK() const { return K; }
};

class VEBtree {
  using Number = unsigned long long;
  VEBtreeNode *root;
  size_t size_;

public:
  VEBtree() : root(new VEBtreeNode(24)), size_(0) {}
  VEBtree(Number universe) : size_(0) {
    Number K = 0;
    for (universe--; universe; universe >>= 1)
      K++;
    root = new VEBtreeNode(K ? K : 1);
  }
  ~VEBtree() { delete root; }

  size_t size() const { return size_; }
  Number min() { return root->min(); }
  Number max() { return root->max(); }
  bool member(Number e) { return root->member(e); }
  Number successor(Number e) { return root->successor(e); }
  Number predecessor(Number e) { return root->predecessor(e); }
  void insert(Number e) {
    if (!root->member(e)) {
      root->insert(e);
      size_++;
    }
  }
  void erase(Number e) {
    if (root->member(e)) {
      root->erase(e);
      size_--;
    }
  }
};

signed main() {
  using namespace std;
  int n;
  cin >> n;
  VEBtree t((unsigned ll)1e9);
  for (int i = 0; i < n; i++) {
    int q;
    cin >> q;
    unsigned long long x, y, prev;
    cin >> x;
    switch (q) {
    case 0:
      t.insert(x);
      cout << t.size() << endl;
      break;
    case 1:
      cout << t.member(x) << endl;
      break;
    case 2:
      t.erase(x);
      break;
    case 3:
      cin >> y;
      x = t.member(x) ? x : t.successor(x);
      if (t.size() > 0) {
        do {
          prev = x;
          cout << x << endl;
          x = t.successor(x);
        } while (prev != x && x <= y);
      }
      break;
    }
  }
  {
    unsigned ll i = t.min(), prev;
    do {
      prev = i;
      i = t.successor(i);
    } while (i != prev);
  }

  return 0;
}