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: Time Limit Exceeded)

#include <iostream>
#include <sstream>  // istringstream
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>

using namespace std;

// 最悪ケースでN^2かかるのでまずい
// string del_kakko(string s){
//     while(true){
//         int ir_idx = s.find("()");
//         if(ir_idx == string::npos){
//             break;
//         }
//         s = s.erase(ir_idx, 2);
//     }    
//     return s;
// }
// string del_kakko(string s){
//     int left = 0, right = 0;
//     for(int i=0; i<s.length(); ++i){
//         if(s[i] == '('){
//             left++;
//         }
//         else if(s[i] == ')'){
//             if(left > 0){
//                 left--;
//             }
//             else{
//                 right++;
//             }
//         }
//     }
//     string ret = "";
//     for(int i=0; i<right; ++i) ret += ")";
//     for(int i=0; i<left; ++i) ret += "(";
//     return ret;
// }

tuple<int, int> del_kakko(string s) {
    int left = 0, right = 0;
    for(int i=0; i<s.length(); ++i){
        if(s[i] == '('){
            left++;
        }
        else if(s[i] == ')'){
            if(left > 0){
                left--;
            }
            else{
                right++;
            }
        }
    }
    return forward_as_tuple(left, right);
}


int main()
{   
    int N;
    cin >> N;
    string S[N];
    for(int i=0; i<N; ++i) cin >> S[i];

    vector<vector<int>> X(N, vector<int>(2));

    for(int i=0; i<N; ++i){
        int left, right;
        tie(left, right) = del_kakko(S[i]);
        // S[i] = del_kakko(S[i]);
        // X[i][1] = S[i].find('(');
        // X[i][0] = S[i].length() - X[i][1];
        X[i][0] = left;
        X[i][1] = right;
        // if(S[i].length() == 0){
        // }
        // else if(S[i][0] == '('){
        //     X[i][0] = S[i].length();
        // }
        // else if(S[i][0] == ')' && S[i][S[i].length()-1] == ')'){
        //     X[i][1] = S[i].length();
        // }
        // else{
        //     X[i][1] = S[i].find('(');
        //     X[i][0] = S[i].length() - X[i][1];
        // }
    }
    // cout << "d " << X[0][0] << " " << X[0][1] << " " << X[1][0] << " " << X[1][1] << endl;

    string ans = "";
    int life = 0;
    // '('のみのもの
    for(int i=0; i<N; ++i){
        if(X[i][1] == 0){
            ans += S[i];
            S[i] = "";
            life += X[i][0];
        }
    }
    // '('の方が多いもの, ただし制限がある
    // ここの処理が最悪ケースでまずいかも
    for(int ii=0; ii<N; ++ii){
        int count = 0;
        for(int i=0; i<N; ++i){
            if(X[i][0] >= X[i][1] && X[i][1] != 0 && X[i][1] <= life){
                ans += S[i];
                S[i] = "";
                life -= X[i][1];
                life += X[i][0];
                count++;
            }
        }
        if(count == 0){
            break;
        }
    }
    // '('の方が多いもの
    for(int i=0; i<N; ++i){
        if(X[i][0] >= X[i][1] && X[i][1] != 0){
            ans += S[i];
            S[i] = "";
        }
    }
    // ')'の方が多いもの
    for(int i=0; i<N; ++i){
        if(X[i][0] < X[i][1] && X[i][0] != 0){
            ans += S[i];
            S[i] = "";
        }
    }
    // ')'のみのもの
    for(int i=0; i<N; ++i){
        if(X[i][0] == 0){
            ans += S[i];
        }
    }

    // cout << "d " << ans << endl;
    // ans = del_kakko(ans);
    int left, right;
    tie(left, right) = del_kakko(ans);
    if(left == 0 && right == 0){
    // if(ans.length() == 0){
        cout << "Yes" << endl;
    }
    else{
        cout << "No" << endl;
    }

    return 0;
}