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


#include <algorithm>
#include <bitset>
#include <cctype>
#include <climits>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <typeinfo>
#include <utility>
#include <vector>
using namespace std;
using Complex = complex<double>;
using ll = long long;
template <typename T>
using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
const ll inf = 1145141919810364364LL;
double PI = acos(-1.0);
#define all(x) (x).begin(), (x).end()
#define puts(x) cout << x << endl
#define rep(i, m, n) for (ll i = m; i < n; ++i)
#define pb push_back
#define fore(i, a) for (auto &i : a)
#define rrep(i, m, n) for (ll i = m; i >= n; --i)

void err() {
  puts("No");
  exit(0);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int N;
  cin >> N;
  vector<pair<int, int>> v1, v2;
  int h = 0;
  for (int i = 0; i < N; i++) {
    string s;
    cin >> s;
    int sum = 0;
    int mi = 0;
    for (int j = 0; j < s.size(); j++) {
      sum += (s[j] == '(') ? 1 : -1;
      mi = min(sum, mi);
    }
    h += sum;
    if (sum > 0) {
      v1.pb({mi, sum});
      continue;
    }

    sum = 0, mi = 0;
    reverse(all(s));
    for (int j = 0; j < s.size(); j++) {
      sum += (s[j] == ')') ? 1 : -1;
      mi = min(sum, mi);
    }
    v2.pb({mi, sum});
  }

  if (h != 0)
    err();

  sort(all(v1));
  reverse(all(v1));
  sort(all(v2));
  reverse(all(v2));

  int z = 0;
  for (int i = 0; i < v1.size(); i++) {
    if (v1[i].first + z < 0)
      err();
    z += v1[i].second;
  }

  z = 0;
  for (int i = 0; i < v2.size(); i++) {
    if (v2[i].first + z < 0)
      err();
    z += v2[i].second;
  }
  puts("Yes");

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cctype>
#include <climits>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <typeinfo>
#include <utility>
#include <vector>
using namespace std;
using Complex = complex<double>;
using ll = long long;
template <typename T>
using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
const ll inf = 1145141919810364364LL;
double PI = acos(-1.0);
#define all(x) (x).begin(), (x).end()
#define puts(x) cout << x << endl
#define rep(i, m, n) for (ll i = m; i < n; ++i)
#define pb push_back
#define fore(i, a) for (auto &i : a)
#define rrep(i, m, n) for (ll i = m; i >= n; --i)

struct Segmenttree {
  static const int N = 1 << 18;
  vector<ll> seg;
  vector<ll> idx;
  void st(ll p, ll v) {
    p += N - 1;
    seg[p] = v;
    idx[p] = p - N + 1;
    while (p > 0) {
      p = (p - 1) / 2;
      seg[p] = max(seg[2 * p + 1], seg[2 * p + 2]);
      if (seg[2 * p + 1] < seg[2 * p + 2])
        idx[p] = idx[2 * p + 2];
      else if (seg[2 * p + 1] > seg[2 * p + 2])
        idx[p] = idx[2 * p + 1];
      else
        idx[p] = min(idx[2 * p + 1], idx[2 * p + 2]);
    }
  }
  pair<ll, ll> query(ll l, ll r, ll a, ll b, ll k) {
    if (r <= a || b <= l)
      return {-inf, inf};
    if (l <= a && b <= r)
      return {seg[k], idx[k]};
    ll m = (a + b) / 2;
    auto p1 = query(l, r, a, m, 2 * k + 1);
    auto p2 = query(l, r, m, b, 2 * k + 2);
    if (p1.first > p2.first)
      return p1;
    else if (p1.first < p2.first)
      return p2;
    else
      return {p1.first, min(p1.second, p2.second)};
  }

  void init() {
    seg.resize(2 * N);
    idx.resize(2 * N);
    for (int i = 0; i < 2 * N; i++)
      seg[i] = -inf;
  }
  //[l,r]
  ll get(int l, int r) { return query(l, r + 1, 0, N, 0).first; }
  ll getidx(int l, int r) { return query(l, r + 1, 0, N, 0).second; }
  pair<ll, ll> getp(int l, int r) { return query(l, r + 1, 0, N, 0); }
};

void err() {
  puts("No");
  exit(0);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int N;
  cin >> N;
  Segmenttree seg = Segmenttree();
  seg.init();
  int cnt1 = 0;
  int cnt2 = 0;
  int z = 0;
  vector<pair<int, int>> v;
  for (int i = 0; i < N; i++) {
    string s;
    cin >> s;
    int cur = 0;
    int mi = 1e9;
    for (int j = 0; j < s.size(); j++) {
      mi = min(cur, mi);
      cnt1 += (s[j] == '(');
      cnt2 += (s[j] == ')');
      cur += (s[j] == '(') ? 1 : -1;
    }
    mi = min(cur, mi);
    v.pb({mi, cur});
  }
  if (cnt1 != cnt2)
    err();

  sort(all(v));
  reverse(all(v));

  for (int i = 0; i < N; i++) {
    seg.st(i, v[i].second);
  }
  int idx = 0;
  while (1) {
    while (idx < N) {
      if (v[idx].first + z >= 0)
        idx++;
      else
        break;
    }
    if (idx == 0)
      break;

    auto p = seg.getp(0, idx - 1);
    ll mx = p.first;
    int i = p.second;

    if (mx < -1e14)
      break;

    z += mx;
    seg.st(i, -inf);
  }

  if (idx == N && seg.get(0, N - 1) < -1e14 && z == 0)
    puts("Yes");
  else
    puts("No");

  return 0;
}