Problem p02686 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0, i##_len = int(n); i < i##_len; ++i)
#define rep(i, a, b) for (int i = int(a); i < int(b); ++i)
#define All(x) (x).begin(), (x).end()
#define rAll(x) (x).rbegin(), (x).rend()
using namespace std;
using ll = long long;

int main() {
  using P = pair<int, int>;
  int N;
  cin >> N;
  vector<P> A(N, make_pair(0, 0));
  int left = 0, right = 0;
  REP(i, N) {
    string s;
    cin >> s;
    REP(j, s.size()) {
      if (s[j] == '(')
        A[i].second++;
      else {
        if (A[i].second > 0)
          A[i].second--;
        else
          A[i].first++;
      }
    }
    if (A[i].first == 0)
      left += A[i].second;
    if (A[i].second == 0)
      right += A[i].first;
  }
  vector<P> f, g;
  REP(i, N) if (A[i].first && A[i].second) {
    if (A[i].second - A[i].first >= 0)
      f.push_back(P(A[i].first, A[i].second - A[i].first));
    else
      g.push_back(P(A[i].first, A[i].second - A[i].first));
  }
  sort(All(f));
  REP(i, f.size()) {
    if (f[i].first <= left)
      left += f[i].second;
    else {
      cout << "No" << endl;
      return 0;
    }
  }
  REP(i, g.size()) {
    if (g[i].first <= left)
      left += g[i].second;
    else {
      cout << "No" << endl;
      return 0;
    }
  }
  if (left == right)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
}


Error: -6
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc


Fixed submission:

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0, i##_len = int(n); i < i##_len; ++i)
#define rep(i, a, b) for (int i = int(a); i < int(b); ++i)
#define All(x) (x).begin(), (x).end()
#define rAll(x) (x).rbegin(), (x).rend()
using namespace std;
using ll = long long;

template <typename T> class SegmentTree {
private:
  typedef std::function<T(T, T)> F;
  int n;
  T d0;
  std::vector<T> vertex;
  F f;

public:
  SegmentTree(F f, T d) : d0(d), f(f) {}
  void init(int _n) {
    n = 1;
    while (n < _n)
      n *= 2;
    vertex.resize(2 * n - 1, d0);
  }
  void build(const std::vector<T> &v) {
    int n_ = v.size();
    init(n_);
    for (int i = 0; i < n_; i++)
      vertex[n + i - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      vertex[i] = f(vertex[2 * i + 1], vertex[2 * i + 2]);
  }
  void update(pair<int, int> i, pair<int, pair<int, int>> x, int que) {
    int k = i.first + n - 1;
    if (que == 0) {
      x.second.second = vertex[k].size();
      vertex[k].push_back(x);
    } else {
      vertex[k][i.second] = x;
    }
    while (k > 0) {
      k = (k - 1) / 2;
      vertex[k] = f(vertex[2 * k + 1], vertex[2 * k + 2]);
    }
    return;
  }
  T query(int l, int r) {
    T vl = d0, vr = d0;
    l += n - 1;
    r += n - 1;
    for (; l <= r; l /= 2, r = r / 2 - 1) {
      if (~l & 1)
        vl = f(vl, vertex[l]);
      if (r & 1)
        vr = f(vertex[r], vr);
    }
    return f(vl, vr);
  }
};

int main() {
  using P = pair<int, int>;
  int N;
  cin >> N;
  vector<P> A(N, make_pair(0, 0));
  int left = 0, right = 0;
  REP(i, N) {
    string s;
    cin >> s;
    REP(j, s.size()) {
      if (s[j] == '(')
        A[i].second++;
      else {
        if (A[i].second > 0)
          A[i].second--;
        else
          A[i].first++;
      }
    }
    if (A[i].first == 0)
      left += A[i].second;
    if (A[i].second == 0)
      right += A[i].first;
  }
  using vp = vector<pair<int, P>>;
  pair<int, P> ei = make_pair(-1e9, P(-1, 0));
  SegmentTree<vp> seg(
      [](vp a, vp b) {
        pair<int, P> res = make_pair(-1e9, P(-1, 0));
        for (auto e : a)
          if (e.first > res.first)
            res = e;
        for (auto e : b)
          if (e.first > res.first)
            res = e;
        return vp({res});
      },
      {ei});
  int cnt = 0;
  seg.init(1e6 + 9);
  REP(i, N) if (A[i].first && A[i].second) {
    cnt++;
    seg.update(make_pair(A[i].first, -1),
               make_pair(A[i].second - A[i].first, make_pair(A[i].first, -1)),
               0);
  }
  while (cnt--) {
    pair<int, P> V = seg.query(0, left)[0];
    left += V.first;
    seg.update(V.second, ei, 1);
  }
  if (left == right)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
}