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

/**
 *    author:  otera
 **/
#include <algorithm>
#include <bitset>
#include <cassert>
#include <ciso646>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;

#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
typedef long double ld;
const int inf = 1e9 + 7;
const ll INF = 1LL << 60;
const ll mod = 1e9 + 7;
#define rep(i, n) for (int i = 0; i < n; i++)
#define per(i, n) for (int i = n - 1; i >= 0; i--)
#define Rep(i, sta, n) for (int i = sta; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define per1(i, n) for (int i = n; i >= 1; i--)
#define Rep1(i, sta, n) for (int i = sta; i <= n; i++)
typedef complex<ld> Point;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<int, int> P;
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(), c.end()
#define pb push_back
#define debug(x) cerr << #x << " = " << (x) << endl;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

void solve() {
  int n;
  cin >> n;
  vector<string> s(n);
  rep(i, n) { cin >> s[i]; }
  vector<int> mi(n, 0), fi(n, 0);
  vector<P> fo, bc;
  rep(i, n) {
    int sz = (int)s[i].size();
    int now = 0;
    rep(j, sz) {
      if (s[i][j] == '(')
        ++now;
      else
        --now;

      chmin(mi[i], now);
    }
    fi[i] = now;
    if (fi[i] >= 0) {
      fo.pb({mi[i], fi[i]});
    } else {
      bc.pb({mi[i], fi[i]});
    }
  }
  sort(all(fo));
  reverse(all(fo));
  sort(all(bc), [&](P x, P y) { return x.sc - x.fr > y.sc - y.fr; });
  int cur = 0;
  rep(i, (int)fo.size()) {
    if (cur + fo[i].fr < 0) {
      cout << "No" << endl;
      return;
    }
    cur += fo[i].sc;
  }
  rep(i, (int)bc.size()) {
    if (cur + bc[i].fr < 0) {
      cout << "No" << endl;
      return;
    }
    cur += bc[i].sc;
  }
  // cerr << cur << endl;
  if (cur != 0) {
    cout << "No" << endl;
  } else {
    cout << "Yes" << endl;
  }
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  // cout << fixed << setprecision(10);
  // int t; cin >> t; rep(i, t)solve();
  solve();
  return 0;
}

Error: -6
malloc(): corrupted top size


Fixed submission:

/**
 *    author:  otera
 **/
#include <algorithm>
#include <bitset>
#include <cassert>
#include <ciso646>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;

#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
typedef long double ld;
const int inf = 1e9 + 7;
const ll INF = 1LL << 60;
const ll mod = 1e9 + 7;
#define rep(i, n) for (int i = 0; i < n; i++)
#define per(i, n) for (int i = n - 1; i >= 0; i--)
#define Rep(i, sta, n) for (int i = sta; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define per1(i, n) for (int i = n; i >= 1; i--)
#define Rep1(i, sta, n) for (int i = sta; i <= n; i++)
typedef complex<ld> Point;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<int, int> P;
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(), c.end()
#define pb push_back
#define debug(x) cerr << #x << " = " << (x) << endl;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

template <typename T> struct RMASegmentTree {
private:
  int n;
  T E;
  vector<T> node;
  inline void updatef(T &x, T &y) {
    x = y;
    // x += y;
    // x = max(x,y);
    // x = min(x,y);
  }
  inline T queryf(T &x, T &y) {
    // return min(x,y);
    // return x+y;
    return max(x, y);
  }

public:
  RMASegmentTree(int sz, T E_) : E(E_) {
    n = 1;
    while (n < sz)
      n <<= 1;
    node.resize(2 * n - 1, E);
  }

  RMASegmentTree(vector<T> &A, T E_) : E(E_) {
    int sz = A.size();
    n = 1;
    while (n < sz)
      n <<= 1;
    node.resize(2 * n - 1, E);
    rep(i, sz) node[i + n - 1] = A[i];
    for (int i = n - 2; i >= 0; --i) {
      node[i] = queryf(node[2 * i + 1], node[2 * i + 2]);
    }
  }
  void update(int k, T x) {
    k += n - 1;
    updatef(node[k], x);
    while (k > 0) {
      k = (k - 1) / 2;
      node[k] = queryf(node[2 * k + 1], node[2 * k + 2]);
    }
  }
  //[a,b)での値を返す
  T get(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (r <= a || b <= l)
      return E;
    if (a <= l && r <= b)
      return node[k];
    T xl = get(a, b, 2 * k + 1, l, (l + r) / 2);
    T xr = get(a, b, 2 * k + 2, (l + r) / 2, r);
    return queryf(xl, xr);
  }
};

template <typename T> struct RMISegmentTree {
private:
  int n;
  T E;
  vector<T> node;
  inline void updatef(T &x, T &y) {
    x = y;
    // x += y;
    // x = max(x,y);
    // x = min(x,y);
  }
  inline T queryf(T &x, T &y) {
    return min(x, y);
    // return x+y;
    // return max(x,y);
  }

public:
  RMISegmentTree(int sz, T E_) : E(E_) {
    n = 1;
    while (n < sz)
      n <<= 1;
    node.resize(2 * n - 1, E);
  }

  RMISegmentTree(vector<T> &A, T E_) : E(E_) {
    int sz = A.size();
    n = 1;
    while (n < sz)
      n <<= 1;
    node.resize(2 * n - 1, E);
    rep(i, sz) node[i + n - 1] = A[i];
    for (int i = n - 2; i >= 0; --i) {
      node[i] = queryf(node[2 * i + 1], node[2 * i + 2]);
    }
  }
  void update(int k, T x) {
    k += n - 1;
    updatef(node[k], x);
    while (k > 0) {
      k = (k - 1) / 2;
      node[k] = queryf(node[2 * k + 1], node[2 * k + 2]);
    }
  }
  //[a,b)での値を返す
  T get(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (r <= a || b <= l)
      return E;
    if (a <= l && r <= b)
      return node[k];
    T xl = get(a, b, 2 * k + 1, l, (l + r) / 2);
    T xr = get(a, b, 2 * k + 2, (l + r) / 2, r);
    return queryf(xl, xr);
  }
};

void solve() {
  int n;
  cin >> n;
  vector<string> s(n);
  rep(i, n) { cin >> s[i]; }
  vector<int> mi(n, 0), fi(n, 0);
  vector<P> fo, bc;
  rep(i, n) {
    int sz = (int)s[i].size();
    int now = 0;
    rep(j, sz) {
      if (s[i][j] == '(')
        ++now;
      else
        --now;

      chmin(mi[i], now);
    }
    fi[i] = now;
    if (fi[i] >= 0) {
      fo.pb({mi[i], i});
    } else {
      bc.pb({mi[i], i});
    }
  }
  sort(all(fo));
  sort(all(bc));
  vector<P> fo1, bc1;
  int now = 0;
  int fsz = (int)fo.size(), bsz = (int)bc.size();
  rep(i, fsz) {
    int j = fo[i].sc;
    fo1.pb({fi[j], j});
  }
  rep(i, bsz) {
    int j = fo[i].sc;
    bc1.pb({fi[j], j});
  }
  //
  RMASegmentTree<P> fseg(fo1, P{-INF, -INF});
  rep(i, fsz) {
    int j = lower_bound(all(fo1), P{-now, -INF}) - fo1.begin();
    P pp = fseg.get(j, fsz);
    int l = pp.sc;
    if (l == -INF) {
      cout << "No" << endl;
      return;
    }
    now += fi[l];
    fo1[l] = {-INF, -INF};
    fseg.update(l, {-INF, -INF});
  }
  //
  RMISegmentTree<P> bseg(bc1, make_pair(-INF, -INF));
  //
  rep(i, (int)bc.size()) {
    if (now + bc[i].fr < 0) {
      cout << "No" << endl;
      return;
    }
    now += bc1[bc[i].sc].fr;
  }
  if (now != 0) {
    cout << "No" << endl;
    return;
  }
  cout << "Yes" << endl;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  // cout << fixed << setprecision(10);
  // int t; cin >> t; rep(i, t)solve();
  solve();
  return 0;
}