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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define REP(i, n) for (ll i = 0; i < (n); ++i)
#define RREP(i, n) for (ll i = (n)-1; i >= 0; --i)
#define ALL(v) (v).begin(), (v).end()

const string YES = "Yes";
const string NO = "No";

int main() {
  ll n;
  cin >> n;
  vector<pair<ll, ll>> up, down;
  REP(i, n) {
    ll cur = 0, bottom = 0;
    string s;
    cin >> s;
    for (char c : s) {
      if (c == '(') {
        cur++;
      } else {
        cur--;
      }
      bottom = min(cur, bottom);
    }
    if (cur >= 0) {
      up.emplace_back(bottom, cur);
    } else {
      down.emplace_back(bottom - cur, -cur);
    }
  }

  sort(up.rbegin(), up.rend());
  ll cur_up = 0;
  for (auto p : up) {
    ll btm = p.first;
    if (cur_up + btm < 0) {
      cout << NO << endl;
      return 0;
    }
    cur_up += p.second;
  }

  sort(down.rbegin(), down.rend());
  ll cur_down = 0;
  for (auto p : down) {
    ll btm = p.first;
    if (cur_down + btm < 0) {
      cout << NO << endl;
      return 0;
    }
    cur_down += p.second;
  }

  if (cur_up != cur_down) {
    cout << NO << endl;
  } else {
    cout << YES << endl;
  }
  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define REP(i, n) for (ll i = 0; i < (n); ++i)
#define RREP(i, n) for (ll i = (n)-1; i >= 0; --i)
#define ALL(v) (v).begin(), (v).end()

const pair<ll, ll> ZERO = {numeric_limits<ll>::min(), -1LL};

template <typename T, T F(const T &, const T &)> struct SegmentTree {
  ll n;
  vector<T> v;

  SegmentTree(ll n_) {
    n = 1;
    while (n < n_) {
      n *= 2;
    }
    v.resize(2 * n - 1);
    fill(v.begin(), v.end(), ZERO);
  }

  // zero-indexed
  void update(ll k, T a) {
    k += n - 1;
    v[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      v[k] = F(v[k * 2 + 1], v[k * 2 + 2]);
    }
  }

  // [a, b), zero-indexed
  T query(ll a, ll b) const { return query_internal(a, b, 0, 0, n); }

  T get(ll a) const { return query(a, a + 1); }

  T query_internal(ll a, ll b, ll k, ll l, ll r) const {
    if (r <= a || b <= l) {
      return ZERO;
    }
    if (a <= l && r <= b) {
      return v[k];
    } else {
      T v1 = query_internal(a, b, k * 2 + 1, l, (l + r) / 2);
      T v2 = query_internal(a, b, k * 2 + 2, (l + r) / 2, r);
      return F(v1, v2);
    }
  }
};

const string YES = "Yes";
const string NO = "No";

pair<ll, ll> max_with_index(const pair<ll, ll> &x, const pair<ll, ll> &y) {
  if (x.first >= y.first) {
    return x;
  } else {
    return y;
  }
}

int main() {
  ll n;
  cin >> n;
  vector<pair<ll, ll>> s; // (n_), n_()
  REP(i, n) {
    string t;
    cin >> t;
    ll h = 0, b = 0;
    for (char c : t) {
      if (c == '(') {
        h++;
      } else {
        h--;
      }
      b = min(h, b);
    }
    s.emplace_back(-b, h);
  }
  sort(ALL(s));

  SegmentTree<pair<ll, ll>, max_with_index> st(n);
  REP(i, n) { st.update(i, make_pair(s.at(i).second, i)); }

  ll rest = 0;
  REP(i, n) {
    const ll j = lower_bound(ALL(s), make_pair(rest + 1, -1LL)) - s.begin();
    const auto p = st.query(0, j);
    const ll k = p.second;
    if (k == -1) {
      cout << NO << endl;
      return 0;
    } else {
      assert(rest >= s.at(k).first);
      rest += s.at(k).second;
      st.update(k, make_pair(numeric_limits<ll>::min(), -1LL));
    }
  }
  if (rest > 0) {
    cout << NO << endl;
  } else {
    cout << YES << endl;
  }
  return 0;
}