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

/*"Success isn't permanent, failure isn't fatal,
                             it's the courage to continue that counts"*/
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
// typedef tree<int, null_type, less<int>, rb_tree_tag,
// tree_order_statistics_node_update> ordered_set;
#define ll long long
#define scn(n) scanf("%d", &n)
#define lscn(n) scanf("%lld", &n)
#define lpri(n) printf("%lld", n)
#define pri(n) printf("%d", n)
#define pln() printf("\\n")
#define priln(n) printf("%d\\n", n)
#define lpriln(n) printf("%lld\\n", n)
#define rep(i, init, n) for (int i = init; i < n; i++)
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define gcd __gcd
#define inf INT_MAX
#define ninf INT_MIN
const int mod = 1e9 + 7;
const int N = 1e6 + 4;

int main() {
  int n;

  scn(n);

  vector<pair<int, int>> pos, neg;

  int support = 0, sum = 0;

  rep(i, 0, n) {
    string s;
    cin >> s;

    int balance = 0, prefix_min = inf;

    for (char x : s) {
      if (x == '(')
        balance++;
      else
        balance--;

      prefix_min = min(prefix_min, balance);
    }

    if (prefix_min >= 0)
      support += balance;
    else {
      if (balance > 0)
        pos.emplace_back(prefix_min, balance);
      else
        neg.emplace_back(prefix_min - balance, balance);
    }

    sum += balance;
  }

  if (sum != 0) {
    printf("No");
    return 0;
  }

  sort(pos.rbegin(), pos.rend());

  sort(neg.begin(), neg.end());

  for (auto it : pos) {
    if (it.F + support < 0) {
      printf("No");
      return 0;
    }

    support += it.S;
  }

  for (auto it : neg) {
    int min_here = it.F + it.S;

    if (support + min_here < 0) {
      printf("No");
      return 0;
    }

    support += it.S;
  }

  printf("Yes");

  return 0;
}


Error: WA

Fixed submission:

/*"Success isn't permanent, failure isn't fatal,
                             it's the courage to continue that counts"*/
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
// typedef tree<int, null_type, less<int>, rb_tree_tag,
// tree_order_statistics_node_update> ordered_set;
#define ll long long
#define scn(n) scanf("%d", &n)
#define lscn(n) scanf("%lld", &n)
#define lpri(n) printf("%lld", n)
#define pri(n) printf("%d", n)
#define pln() printf("\\n")
#define priln(n) printf("%d\\n", n)
#define lpriln(n) printf("%lld\\n", n)
#define rep(i, init, n) for (int i = init; i < n; i++)
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define gcd __gcd
#define inf INT_MAX
#define ninf INT_MIN
const int mod = 1e9 + 7;
const int N = 1e6 + 4;
const int lim = 61;

vector<int> sv[2 * N + 4];

int pre_min[N];

int tree[8 * N + 100];

void build(int node, int st, int end) {
  if (st == end) {
    if (sv[st].size())
      tree[node] = st;
    else
      tree[node] = -1;

    return;
  }

  int mid = (st + end) / 2;

  build(2 * node, st, mid);
  build(2 * node + 1, mid + 1, end);

  int ind1 = tree[2 * node], ind2 = tree[2 * node + 1];

  if (ind1 != -1 and ind2 != -1) {
    if (sv[ind1].back() > sv[ind2].back())
      tree[node] = ind1;
    else
      tree[node] = ind2;
  } else if (ind1 != -1)
    tree[node] = ind1;
  else if (ind2 != -1)
    tree[node] = ind2;
  else
    tree[node] = -1;
}

void update(int node, int st, int end, int ind) {
  if (st == end) {
    sv[st].pop_back();

    if (sv[st].size())
      tree[node] = st;
    else
      tree[node] = -1;

    return;
  }

  int ind1 = tree[2 * node], ind2 = tree[2 * node + 1];

  int mid = (st + end) / 2;

  if (ind <= mid)
    update(2 * node, st, mid, ind);
  else
    update(2 * node + 1, mid + 1, end, ind);

  if (ind1 != -1 and ind2 != -1) {
    if (sv[ind1].back() > sv[ind2].back())
      tree[node] = ind1;
    else
      tree[node] = ind2;
  } else if (ind1 != -1)
    tree[node] = ind1;
  else if (ind2 != -1)
    tree[node] = ind2;
  else
    tree[node] = -1;
}

int query(int node, int st, int end, int l, int r) {
  if (st >= l and end <= r)
    return tree[node];

  if (st > r or end < l)
    return -1;

  int mid = (st + end) / 2;

  int ind1 = query(2 * node, st, mid, l, r),
      ind2 = query(2 * node + 1, mid + 1, end, l, r);

  if (ind1 != -1 and ind2 != -1) {
    if (sv[ind1].back() > sv[ind2].back())
      return ind1;
    else
      return ind2;
  } else if (ind1 != -1)
    return ind1;
  else if (ind2 != -1)
    return ind2;
  else
    return -1;
}

int main() {
  int n, sum = 0;

  scn(n);

  rep(i, 0, 8 * N + 100) tree[i] = -1;

  vector<pair<int, string>> v(n), vv(n);

  rep(i, 0, n) {
    cin >> v[i].S;

    string s = v[i].S;

    v[i].F = 0;

    pre_min[i] = inf;

    rep(j, 0, s.size()) {
      if (s[j] == '(')
        v[i].F++;
      else
        v[i].F--;

      pre_min[i] = min(pre_min[i], v[i].F);
    }

    sv[pre_min[i] + N].pb(v[i].F);

    sum += v[i].F;
  }

  if (sum != 0) {
    cout << "No";

    return 0;
  }

  int cur_balance = 0;

  rep(i, 0, 2 * N) sort(sv[i].begin(), sv[i].end());

  build(1, 1, 2 * N);

  rep(i, 0, n) {
    int here = query(1, 1, 2 * N, -cur_balance + N, 2 * N);

    // cout<<cur_balance<<" "<<here<<" "<<sv[here].back()<<endl;

    if (here == -1) {
      cout << "No";
      return 0;
    }

    cur_balance += sv[here].back();

    update(1, 1, 2 * N, here);
  }

  cout << "Yes";

  return 0;
}