Problem p02686 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, j, k) for (int i = (int)(j); i <= (int)(k); i++)
#define debug(x) cerr << #x << ":" << (x) << endl
#define fix cout << fixed << setprecision(20);
#define int long long
const int maxn = (int)1e6 + 5;
int a[maxn], b[maxn], idx[maxn];
bool cmp(int i, int j) {
  if ((b[i] - a[i]) * (b[j] - a[j]) < 0) {
    return b[i] - a[i] > 0;
  }
  if (b[i] - a[i] > 0) {
    return a[i] < a[j];
  }
  return b[i] > b[j];
}
string ss[maxn];

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  rep(i, 1, n) {
    string s;
    cin >> s;
    int now = 0;
    int mx = 0, mn = 0;
    for (auto c : s) {
      if (c == ')')
        now++;
      else
        now--;
      mx = max(mx, now);
    }
    reverse(s.begin(), s.end());
    now = 0;
    for (auto c : s) {
      if (c == '(')
        now++;
      else
        now--;
      mn = max(mn, now);
    }
    a[i] = mx, b[i] = mn;
    reverse(s.begin(), s.end());
    ss[i] = s;
  }
  rep(i, 1, n) idx[i] = i;
  sort(idx + 1, idx + 1 + n, cmp);
  int now = 0;
  int flag = 1;
  rep(i, 1, n) {
    int j = idx[i];
    // debug(j);
    // debug(a[j]),debug(b[j]);
    for (auto c : ss[j]) {
      if (c == '(')
        now++;
      else
        now--;
      if (now < 0)
        flag = 0;
    }
    // debug(now);
  }
  if (now != 0)
    flag = 0;
  cout << (flag ? "Yes" : "No") << endl;
}
/*
4
)))((
)))(
))(((
)(((

需要查询区间最大值的位置，单点删除

换种思路，
1.删除多余的，必定剩下 ))(((， 否则在后缀的)会被消掉
2。 前面放（多的，
3.前面）越少越前面，后面（越少越后面
 */

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, j, k) for (int i = (int)(j); i <= (int)(k); i++)
#define debug(x) cerr << #x << ":" << (x) << endl
#define fix cout << fixed << setprecision(20);
#define int long long
const int maxn = (int)1e6 + 5;
int a[maxn], b[maxn], idx[maxn];
bool cmp(int i, int j) { // 逻辑较复杂
  if (b[i] == a[i] and a[j] == b[j]) {
    return a[i] < b[j];
  }
  if (b[i] == a[i])
    return b[j] - a[j] < 0;
  if (b[j] == a[j])
    return b[i] - a[i] > 0;
  if ((b[i] - a[i]) * (b[j] - a[j]) < 0) {
    return b[i] - a[i] > 0;
  }
  if (b[i] - a[i] > 0) {
    return a[i] < a[j];
  }
  return b[i] > b[j];
}
string ss[maxn];

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  rep(i, 1, n) {
    string s;
    cin >> s;
    int now = 0;
    int mx = 0, mn = 0;
    for (auto c : s) {
      if (c == ')')
        now++;
      else
        now--;
      mx = max(mx, now);
    }
    reverse(s.begin(), s.end());
    now = 0;
    for (auto c : s) {
      if (c == '(')
        now++;
      else
        now--;
      mn = max(mn, now);
    }
    a[i] = mx, b[i] = mn;
    reverse(s.begin(), s.end());
    ss[i] = s;
  }
  rep(i, 1, n) idx[i] = i;
  sort(idx + 1, idx + 1 + n, cmp);
  int now = 0;
  int flag = 1;
  rep(i, 1, n) {
    int j = idx[i];
    // debug(j);
    // debug(a[j]),debug(b[j]);
    for (auto c : ss[j]) {
      if (c == '(')
        now++;
      else
        now--;
      if (now < 0)
        flag = 0;
    }
    // debug(now);
  }
  if (now != 0)
    flag = 0;
  cout << (flag ? "Yes" : "No") << endl;
}
/*
4
)))((
)))(
))(((
)(((

需要查询区间最大值的位置，单点删除

换种思路，
1.删除多余的，必定剩下 ))(((， 否则在后缀的)会被消掉
2。 前面放（多的，
3.前面）越少越前面，后面（越少越后面
 */