Problem:
Score : 600 points

Problem Statement

A bracket sequence is a string that is one of the following:

An empty string;

The concatenation of (, A, and ) in this order, for some bracket sequence A ;

The concatenation of A and B in this order, for some non-empty bracket sequences A and B /

Given are N strings S_i. Can a bracket sequence be formed by concatenating all the N strings in some order?

Constraints

1 \leq N \leq 10^6

The total length of the strings S_i is at most 10^6.

S_i is a non-empty string consisting of ( and ).

Input

Input is given from Standard Input in the following format:

N
S_1
:
S_N

Output

If a bracket sequence can be formed by concatenating all the N strings in some order, print Yes; otherwise, print No.

Sample Input 1

2
)
(()

Sample Output 1

Yes

Concatenating (() and ) in this order forms a bracket sequence.

Sample Input 2

2
)(
()

Sample Output 2

No

Sample Input 3

4
((()))
((((((
))))))
()()()

Sample Output 3

Yes

Sample Input 4

3
(((
)
)

Sample Output 4

No

Solution in C++ (GCC 9.2.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < n; i++)
#define rep2(i, x, n) for(int i = x; i <= n; i++)
#define rep3(i, x, n) for(int i = x; i >= n; i--)
#define elif else if
#define sp(x) fixed << setprecision(x)
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;
const ll MOD = 1e9+7;
//const ll MOD = 998244353;
const int inf = (1<<30)-1;
const ll INF = (1LL<<60)-1;
const ld EPS = 1e-10;
template<typename T> bool chmax(T &x, const T &y) {return (x < y)? (x = y, true) : false;};
template<typename T> bool chmin(T &x, const T &y) {return (x > y)? (x = y, true) : false;};

template<typename Monoid> struct Segment_Tree{
    //二項演算
    Monoid ope(Monoid a, Monoid b) {return max(a, b);}
    //単位元
    Monoid unit;
    int n;
    vector<Monoid> seg;
    //要素数N(0-indexed)のxを単位元とするセグメント木を構築
    Segment_Tree(int N, Monoid x){
        unit = x;
        n = 1;
        while(n < N) n <<= 1;
        seg.assign(2*n, unit);
    }
    //i番目の要素をxに変更
    void change(int i, Monoid x){
        i += n;
        seg[i] = x;
        while(i > 0){
            i /= 2;
            seg[i] = ope(seg[2*i], seg[2*i+1]);
        }
    }
    //query(a, b)で[a, b)における演算の結果を取得
    Monoid query(int a, int b, int i = 1, int l = 0, int r = -1){
        if(r < 0) r = n;
        if(a >= r || b <= l) return unit;
        elif(a <= l && r <= b) return seg[i];
        else{
            Monoid vl = query(a, b, 2*i, l, (l+r)/2);
            Monoid vr = query(a, b, 2*i+1, (l+r)/2, r);
            return ope(vl, vr);
        }
    }
    //i番目の要素を取得
    Monoid at(int i){
        return seg[n+i]; 
    }
    //初期化する
    void clear(){
        fill(seg.begin(), seg.end(), unit);
    }
};

int main(){
    int N;
    cin >> N;
    string S[N];
    rep(i, N) cin >> S[i];
    //m[i]:=S[i]が最小でどこまで減るか
    int m[N], a[N];
    rep(i, N){
        int now = 0;
        m[i] = 0;
        rep(j, sz(S[i])){
            if(S[i][j] == '(') now++;
            else now--;
            chmin(m[i], now);
        }
        a[i] = now;
    }
    Segment_Tree<pii> seg(N, pii(-inf, -inf));
    pii p[N];
    rep(i, N) p[i] = pii(m[i], a[i]);
    sort(p, p+N, greater<pii>());
    rep(i, N){
        seg.change(i, pii(p[i].second, i));
    }
    int MAX = 2e6;
    int L[MAX];
    int now = 0;
    rep(i, MAX){
        while(now < N && p[now].first == -i) now++;
        L[i] = now;
    }
    ll sum = 0;
    rep(i, N){
        pii res = seg.query(0, L[sum]);
        sum += res.first;
        if(sum < 0){
            cout << "No" << endl;
            return 0;
        }
        seg.change(res.second, pii(-inf, -inf));
    }
    if(sum == 0) cout << "Yes" << endl;
    else cout << "No" << endl;
}