Problem p02289 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <functional>
#include <iostream>
#include <string>

template <class T> class Vector {
protected:
  int sz, cap;
  T *p;

public:
  Vector() : sz(0), cap(0), p(0) {}
  ~Vector() { clear(); }
  void swap(Vector &v) {
    std::swap(sz, v.sz);
    std::swap(cap, v.cap);
    std::swap(p, v.p);
  }
  int size() const { return sz; }
  bool empty() const { return !sz; }
  void push_back(T v) {
    if (sz == cap)
      reserve(sz ? sz * 2 : 1);
    new (p + sz++) T(v);
  }
  void pop_back() {
    p[--sz].~T();
    if (sz && sz * 4 < cap) {
      reserve(cap / 2);
    }
  }
  void resize(int n) {
    clear();
    if (n == 0)
      return;
    cap = 1;
    while (cap < n)
      cap *= 2;
    reserve(cap);
    for (int i = 0; i < n; i++)
      new (p + i) T();
    sz = n;
  }
  void reserve(int n) {
    T *p = (T *)operator new(n * sizeof(T));
    for (int i = 0; i < sz; i++) {
      new (p + i) T(this->p[i]);
      this->p[i].~T();
    }
    if (this->p)
      operator delete(this->p);
    this->p = p;
    cap = n;
  }
  void clear() {
    for (int i = 0; i < sz; i++) {
      p[i].~T();
    }
    if (p)
      operator delete(p);
    sz = cap = 0;
    p = 0;
  }
  T &operator[](int i) const { return p[i]; }
  T &front() const { return p[0]; }
  T &back() const { return p[sz - 1]; }
};

template <class T, class C = std::less<T>>
class BinaryHeap : private Vector<T> {
  C cmp;

public:
  void push(T v) {
    Vector<T>::push_back(v);
    int i = Vector<T>::size();
    T *const q = Vector<T>::p - 1;
    while (1 < i && cmp(q[i], q[i / 2])) {
      std::swap(q[i / 2], q[i]);
      i /= 2;
    }
  }
  T top() const { return Vector<T>::p[0]; }
  void pop() {
    std::swap(Vector<T>::front(), Vector<T>::back());
    Vector<T>::pop_back();
    int i = 1;
    T *const q = Vector<T>::p - 1;
    while (i * 2 <= Vector<T>::size()) {
      int j = 2 * i;
      if (j + 1 <= Vector<T>::size() && cmp(q[j + 1], q[j]))
        j++;
      if (cmp(q[j], q[i])) {
        std::swap(q[i], q[j]);
        i = j;
      } else
        break;
    }
  }
  bool empty() const { return Vector<T>::empty(); }
};

using namespace std;

int main() {
  BinaryHeap<int, greater<int>> heap;
  string s;
  while (1) {
    cin >> s;
    if (s == "end")
      break;
    if (s == "insert") {
      int n;
      cin >> n;
      heap.push(n);
    } else if (s == "extract") {
      cout << heap.top() << endl;
      heap.pop();
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

template <class T> class BinomialHeap {
  struct Tree {
    T val;
    Tree *child, *next;
    Tree() {}
    Tree(T &v) : val(v), child(0), next(0) {}
    ~Tree() {
      if (child)
        delete child;
      if (next)
        delete next;
    }
  };
  std::vector<Tree *> trees;
  mutable int imax;

  static Tree *add(Tree *a, Tree *b) {
    if (a->val > b->val) {
      b->next = a->child;
      a->child = b;
      return a;
    } else {
      a->next = b->child;
      b->child = a;
      return b;
    }
  }
  void findmax() const {
    for (int i = 0; i < trees.size(); i++)
      if (trees[i] && (imax == -1 || trees[i]->val > trees[imax]->val))
        imax = i;
  }
  BinomialHeap(int n) : trees(n) {}

public:
  BinomialHeap() : imax(-1) {}
  ~BinomialHeap() { clear(); }
  // O(log n)
  void meld(BinomialHeap &h) {
    imax = -1;
    Tree *carry = NULL;
    if (trees.size() < h.trees.size())
      trees.swap(h.trees);
    for (int i = 0; i < trees.size(); i++) {
      if (carry) {
        if (i < h.trees.size() && h.trees[i]) {
          carry = add(carry, h.trees[i]);
        } else if (trees[i]) {
          carry = add(carry, trees[i]);
          trees[i] = NULL;
        } else {
          trees[i] = carry;
          carry = NULL;
        }
      } else if (i < h.trees.size() && h.trees[i]) {
        if (trees[i]) {
          carry = add(trees[i], h.trees[i]);
          trees[i] = NULL;
        } else {
          trees[i] = h.trees[i];
        }
      }
    }
    h.trees.clear();
    if (carry)
      trees.push_back(carry);
  }
  // O(log n)
  void push(T &v) {
    imax = -1;
    /*BinomialHeap h(1);
    h.trees[0]=new Tree(v);
    meld(h);*/
    Tree *carry = new Tree(v);
    for (int i = 0; carry && i < trees.size(); i++) {
      if (carry) {
        if (trees[i]) {
          carry = add(carry, trees[i]);
          trees[i] = NULL;
        } else {
          trees[i] = carry;
          carry = NULL;
        }
      }
    }
    if (carry)
      trees.push_back(carry);
  }
  T getmax() const {
    if (imax == -1)
      findmax();
    return trees[imax]->val;
  }
  void popmax() {
    if (imax == -1)
      findmax();
    if (imax == 0) {
      delete trees[0];
      trees[0] = NULL;
    } else {
      BinomialHeap h(imax);
      Tree *p, *t = trees[imax]->child;
      int i = imax;
      while (t) {
        h.trees[--i] = t;
        p = t;
        t = t->next;
        p->next = NULL;
      }
      trees[imax]->child = NULL;
      delete trees[imax];
      trees[imax] = NULL;
      meld(h);
    }
    while (!trees.empty() && trees.back() == NULL)
      trees.pop_back();
    imax = -1;
  }
  bool empty() const { return trees.empty(); }
  void clear() {
    imax = -1;
    for (int i = 0; i < trees.size(); i++)
      if (trees[i])
        delete trees[i];
    trees.clear();
  }
  // void remove(int id){}
  // decrease_key remove(int id,T v){}
};

using namespace std;

int main() {
  BinomialHeap<int> heap;
  string s;
  while (1) {
    cin >> s;
    if (s == "end")
      break;
    if (s == "insert") {
      int n;
      cin >> n;
      heap.push(n);
    } else if (s == "extract") {
      cout << heap.getmax() << endl;
      heap.popmax();
    }
  }
  return 0;
}