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

#ifndef ONLINE_JUDGE
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>

#define PI 3.14159265359
using namespace std;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define bit(n, k) (((ll)n >> (ll)k) & 1) /*nのk bit目*/
#define pb push_back
#define pf push_front
#define FI first
#define SE second
#define eb emplace_back
#define SZ(x) ((ll)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const long long INF = 1e+18 + 1;
// long long INF=(1LL<<31)-1;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vector<ll>> vvl;
typedef pair<ll, ll> P;
typedef tuple<ll, ll, ll> T;
typedef struct Point_Coordinates {
  ll x, y;
} point;
const ll MOD = 1000000007LL;
// ll MOD=1000000007LL;
// const ll MOD=998244353LL;
// const ll MOD=1777777777LL;
// const ll MAX_V=114514LL;
// const ll MAX = 500010LL;
const ll mod = MOD;
string abc = "abcdefghijklmnopqrstuvwxyz";
string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
vl dx = {0, 0, 1, -1};
vl dy = {1, -1, 0, 0};

// 素因数分解O(√n)
map<ll, ll> prime_factor(ll n) {
  map<ll, ll> res;
  for (ll i = 2; i * i <= n; i++) {
    while (n % i == 0) {
      res[i]++;
      n /= i;
    }
  }
  if (n != 1)
    res[n] = 1;
  return res;
}

const ll MAX = 2000010;
long long fac[MAX], finv[MAX], inv[MAX];
// finvが階乗の逆元

// テーブルを作る前処理
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (ll i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算
long long COM(ll n, ll k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

ll modpow(ll a, ll n) {

  ll res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}

/*Eratosthenes()
ll N=2000010;
vl arr(N);
void Eratosthenes(){
        for(ll i = 0; i < N; i++){
                arr[i] = 1;
        }
        arr[1]=0;
        for(ll i = 2; i < sqrt(N); i++){
                if(arr[i]){
                        for(ll j = 0; i * (j + 2) < N; j++){
                                arr[i *(j + 2)] = 0;
                        }
                }
        }
}*/
// 素数判定O(√n)
bool is_prime(ll n) {
  for (ll i = 2; i * i <= n; i++) {
    if (n % i == 0)
      return false;
  }
  return n != 1;
}

// 約数の列挙O(√n)
vector<ll> divisor(ll n) {
  vector<ll> res;
  for (ll i = 1; i * i <= n; i++) {
    if (n % i == 0) {
      res.push_back(i);
      if (i != n / i)
        res.push_back(n / i);
    }
  }
  return res;
}

/* SegTree<X>(n,fx,ex): モノイド(集合X, 二項演算fx,
   単位元ex)についてサイズnで構築 set(int i, X x), build():
   i番目の要素をxにセット。まとめてセグ木を構築する。O(n) update(i,x): i
   番目の要素を x に更新。O(log(n)) query(a,b):  [a,b)
   全てにfxを作用させた値を取得。O(log(n))
*/
template <typename X> struct SegTree {
  using FX = function<X(X, X)>;
  int n;
  FX fx;
  const X ex;
  vector<X> dat;
  SegTree(int n_, FX fx_, X ex_) : n(), fx(fx_), ex(ex_), dat(n_ * 4, ex_) {
    int x = 1;
    while (n_ > x) {
      x *= 2;
    }
    n = x;
  }

  void set(int i, X x) { dat[i + n - 1] = x; }
  void build() {
    for (int k = n - 2; k >= 0; k--)
      dat[k] = fx(dat[2 * k + 1], dat[2 * k + 2]);
  }

  void update(int i, X x) {
    i += n - 1;
    dat[i] = x;
    while (i > 0) {
      i = (i - 1) / 2; // parent
      dat[i] = fx(dat[i * 2 + 1], dat[i * 2 + 2]);
    }
  }

  // the minimum element of [a,b)
  X query(int a, int b) { return query_sub(a, b, 0, 0, n); }
  X query_sub(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) {
      return ex;
    } else if (a <= l && r <= b) {
      return dat[k];
    } else {
      X vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);
      X vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
      return fx(vl, vr);
    }
  }
  /* debug */
  inline X operator[](int a) { return query(a, a + 1); }
  void print() {
    for (int i = 0; i < 2 * n - 1; ++i) {
      cout << (*this)[i];
      if (i != n)
        cout << ",";
    }
    cout << endl;
  }
  /*
  使用例
  auto fx=[](int x1,int x2)->int{return max(x1,x2);};
  ll ex=0;
  SegTree<ll>rmq(n,fx,ex);*/
};

/* Trie 木： 文字の種類(char_size)、int型で0に対応する文字(base)
    insert(word): 単語 word を Trie 木に挿入する
    search(word): 単語 word が Trie 木にあるか判定する
    start_with(prefix):  prefix が一致する単語が Trie 木にあるか判定する
    count(): 挿入した単語の数を返す
    size(): Trie 木の頂点数を返す
    計算量：insert, search ともに O(M)（Mは単語の長さ）
*/
template <int char_size, int base> struct Trie {
  struct Node {       // 頂点を表す構造体
    vector<int> next; // 子の頂点番号を格納。存在しなければ-1
    vector<int> accept; // 末端がこの頂点になる単語の word_id を保存
    int c;              // base からの間隔をint型で表現したもの
    int common; // いくつの単語がこの頂点を共有しているか
    Node(int c_) : c(c_), common(0) { next.assign(char_size, -1); }
  };
  vector<Node> nodes; // trie 木本体
  int root;
  Trie() : root(0) { nodes.push_back(Node(root)); }
  // 単語の挿入
  void insert(const string &word, int word_id) {
    int node_id = 0;
    for (int i = 0; i < (int)word.size(); i++) {
      int c = (int)(word[i] - base);
      int &next_id = nodes[node_id].next[c];
      if (next_id == -1) { // 次の頂点が存在しなければ追加
        next_id = (int)nodes.size();
        nodes.push_back(Node(c));
      }
      ++nodes[node_id].common;
      node_id = next_id;
    }
    ++nodes[node_id].common;
    nodes[node_id].accept.push_back(word_id);
  }
  void insert(const string &word) { insert(word, nodes[0].common); }
  // 単語とprefixの検索
  bool search(const string &word, bool prefix = false) {
    int node_id = 0;
    for (int i = 0; i < (int)word.size(); i++) {
      int c = (int)(word[i] - base);
      int &next_id = nodes[node_id].next[c];
      if (next_id == -1) { // 次の頂点が存在しなければ終了
        return false;
      }
      node_id = next_id;
    }
    return (prefix) ? true : nodes[node_id].accept.size() > 0;
  }
  // prefix を持つ単語が存在するかの検索
  bool start_with(const string &prefix) { return search(prefix, true); }
  // 挿入した単語の数
  int count() const { return (nodes[0].common); }
  // Trie木のノード数
  int size() const { return ((int)nodes.size()); }
};

// union by size + path having
class UnionFind {
public:
  vector<ll> par; // 各元の親を表す配列
  vector<ll> siz; // 素集合のサイズを表す配列(1 で初期化)

  // Constructor
  UnionFind(ll sz_) : par(sz_), siz(sz_, 1LL) {
    for (ll i = 0; i < sz_; ++i)
      par[i] = i; // 初期では親は自分自身
  }
  void init(ll sz_) {
    par.resize(sz_);
    siz.assign(sz_, 1LL); // resize だとなぜか初期化されなかった
    for (ll i = 0; i < sz_; ++i)
      par[i] = i; // 初期では親は自分自身
  }

  // Member Function
  // Find
  ll root(ll x) { // 根の検索
    while (par[x] != x) {
      x = par[x] = par[par[x]]; // x の親の親を x の親とする
    }
    return x;
  }

  // Union(Unite, Merge)
  bool merge(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    // merge technique（データ構造をマージするテク．小を大にくっつける）
    if (siz[x] < siz[y])
      swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(ll x, ll y) { // 連結判定
    return root(x) == root(y);
  }

  ll size(ll x) { // 素集合のサイズ
    return siz[root(x)];
  }
};

// 0-indexed parmutation only
vvl cycle_partition(const vl &p) {
  ll n = p.size();
  vvl ret;
  vector<bool> check(n, false);
  rep(i, n) if (!check[p[i]]) {
    vl v;
    ll pos = p[i];
    v.pb(i);
    check[i] = true;
    while (pos != i) {
      v.pb(pos);
      check[pos] = true;
      pos = p[pos];
    }
    ret.pb(v);
  }
  return ret;
}

// Manachar　修理中
//  vl Manachar(string S){
//      ll c=0,n=S.size();
//      vl R(n,1);
//      for(ll i=0;i<n;i++){
//          ll l=c-(i-c);
//          if(i+R[l]<c+R[c]){
//              R[i]=R[l];
//          }else{
//              ll j=c+R[c]-i;
//              while(i-j>=0 && i+j<n && S[i-j] == S[i+j])j++;
//              R[i]=j;
//              c=i;
//          }
//      }
//      return R;
//  }

struct edge {
  ll to;
  ll cost;
};

template <typename T> T pow(T a, long long n, T e = 1) {
  T ret = e;
  while (n) {
    if (n & 1)
      ret *= a;
    a *= a;
    n >>= 1;
  }
  return ret;
}

template <int mod> struct ModInt {
  int x;
  ModInt() : x(0) {}
  ModInt(long long x_) {
    if ((x = x_ % mod + mod) >= mod)
      x -= mod;
  }
  ModInt &operator+=(ModInt rhs) {
    if ((x += rhs.x) >= mod)
      x -= mod;
    return *this;
  }
  ModInt &operator-=(ModInt rhs) {
    if ((x -= rhs.x) < 0)
      x += mod;
    return *this;
  }
  ModInt &operator*=(ModInt rhs) {
    x = (unsigned long long)x * rhs.x % mod;
    return *this;
  }
  ModInt &operator/=(ModInt rhs) {
    x = (unsigned long long)x * rhs.inv().x % mod;
    return *this;
  }

  ModInt operator-() const { return -x < 0 ? mod - x : -x; }
  ModInt operator+(ModInt rhs) const { return ModInt(*this) += rhs; }
  ModInt operator-(ModInt rhs) const { return ModInt(*this) -= rhs; }
  ModInt operator*(ModInt rhs) const { return ModInt(*this) *= rhs; }
  ModInt operator/(ModInt rhs) const { return ModInt(*this) /= rhs; }
  bool operator==(ModInt rhs) const { return x == rhs.x; }
  bool operator!=(ModInt rhs) const { return x != rhs.x; }
  ModInt inv() const { return pow(*this, mod - 2); }

  friend ostream &operator<<(ostream &s, ModInt<mod> a) {
    s << a.x;
    return s;
  }
  friend istream &operator>>(istream &s, ModInt<mod> &a) {
    s >> a.x;
    return s;
  }
};

using mint = ModInt<MOD>;

int main() {
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  cout << fixed << setprecision(10);
  /*--------------------------------*/

  ll n;
  cin >> n;
  vector<string> s(n);
  rep(i, n) cin >> s[i];
  vector<P> vl;
  vector<P> vr;
  rep(i, n) {
    ll now = 0;
    ll right = 0, left = 0;
    rep(j, s[i].size()) {
      if (s[i][j] == ')')
        now++;
      else
        now--;
      left = max(left, now);
    }
    now = 0;
    for (ll j = s[i].size() - 1; j >= 0; j--) {
      if (s[i][j] == '(')
        now++;
      else
        now--;
      right = max(right, now);
    }
    if (right > left)
      vl.pb(make_pair(left, right));
    else
      vr.pb(make_pair(right, left));
  }
  sort(all(vl));
  sort(all(vr));
  ll nowl = 0, nowr = 0;
  rep(i, vl.size()) {
    nowl += vl[i].FI;
    if (nowl > 0) {
      cout << "No" << endl;
      return 0;
    }
    nowl -= vl[i].SE;
  }
  rep(i, vr.size()) {
    nowr += vr[i].FI;
    if (nowr > 0) {
      cout << "No" << endl;
      return 0;
    }
    nowr -= vr[i].SE;
  }
  if (nowl != nowr) {
    cout << "No" << endl;
  } else
    cout << "Yes" << endl;
}


Error: -11

Fixed submission:

// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
#define PI 3.14159265359
using namespace std;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define bit(n, k) (((ll)n >> (ll)k) & 1) /*nのk bit目*/
const long long INF = 1e+18 + 1;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vector<ll>> vvl;
typedef pair<ll, ll> P;
typedef tuple<ll, ll, ll> T;
// const ll MOD=1000000007LL;
const ll MOD = 998244353LL;
string abc = "abcdefghijklmnopqrstuvwxyz";
string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
vl dx = {-1, -1, -1, 0, 0, 1, 1, 1};
vl dy = {1, -1, 0, 1, -1, 1, 0, -1};

int main() {
  ll n;
  cin >> n;
  vector<string> s(n);
  rep(i, n) cin >> s[i];
  vl MAXR(n);
  vl MAXL(n);
  rep(i, n) {
    ll d = s[i].size();
    ll lastr = 0, lastl = 0, r = 0, l = 0;
    rep(j, d) {
      if (s[i][j] == ')') {
        r++;
        lastr = max(r - l, 0LL);
      } else
        l++;
    }
    r = 0;
    l = 0;
    for (ll j = d - 1; j >= 0; j--) {
      if (s[i][j] == ')')
        r++;
      else {
        l++;
        lastl = max(l - r, 0LL);
      }
    }
    MAXR[i] = lastr;
    MAXL[i] = lastl;
  }
  // rep(i,n)cout<<MAXR[i]<<" "<<MAXL[i]<<" ";
  // cout<<endl;
  vector<P> vec;
  rep(i, n) {
    vec[i].first = MAXL[i];
    vec[i].second = MAXR[i];
  }
  sort(vec.begin(), vec.end());
  ll sumL = 0;
  ll sumR = 0;
  rep(i, n) {
    sumL += vec[i].first;
    sumR += vec[i].second;
    if (sumL > sumR) {
      cout << "No" << endl;
      return 0;
    }
  }
  if (sumR != sumL) {
    cout << "No" << endl;
    return 0;
  }
  cout << "Yes" << endl;
}