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>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
#define gcd(a,b) __gcd((a),(b))
#define lcm(a,b) ((a)*(b))/__gcd((a),(b))
#define vi vector<int>
#define vll vector<long long>
#define vvi vector<vi>
#define mt make_tuple
#define mp make_pair
#define hell 1000000007
#define mod 998244353
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vpii vector<pii>
#define vpll vector<pll>
#define all(a) a.begin(),a.end()
#define ign cin.ignore();
#define g(a,b) get<a>(b)
#define vt(a) vector<a>
#define rep(i,a,b) for(ll i=a;i<b;i++)
#define repi(i,a,b) for(ll i=b-1;i>=a;i--)
#define fi first
#define se second

#define o_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define o_setll tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
//to delete an element
//s.erase(s.find_by_order(s.order_of_key(ele)));
//where s is the name of the ordered_set
//member functions :
//1. order_of_key(k) : number of elements strictly lesser than k
//2. find_by_order(k) : k-th element in the set

using namespace std;
using namespace __gnu_pbds;

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifdef MY_PROJECT
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

tuple<int,int> process(string &s){
    int mini=INT_MAX;
    int delta=0;
    rep(i,0,s.length()){
        if(s[i]=='(')
            delta++;
        else delta--;
        mini=min(mini,delta);
    }
    int required=-mini;
    return make_tuple(delta,required);
}

class Compare2
{
public:
    //delta = +ve, required = +ve
    bool operator() (tuple<int,int> &a, tuple<int,int> &b)
    {
        return g(1,a)>g(1,b);
    }
};

class Compare3
{
public:
    //delta = -ve, required = +ve
    bool operator() (tuple<int,int> &a, tuple<int,int> &b)
    {
        return g(1,a)<g(1,b);
    }
};

class Compare4
{
public:
    //delta = -ve, required = -ve
    bool operator() (tuple<int,int> &a, tuple<int,int> &b)
    {
        return g(1,a)<g(1,b);
    }
};

int main()
{
    IOS
    /*
    freopen("random_01.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    */
    ll ntc=1;
    //cin>>ntc;
    rep(tc,1,ntc+1)
    {
        //cout<<"Case #"<<tc<<": ";
        int n;
        cin>>n;
        string s;
        priority_queue<tuple<int,int>,vector<tuple<int,int>>> pq1;
        priority_queue<tuple<int,int>,vector<tuple<int,int>>,Compare2> pq2;
        priority_queue<tuple<int,int>,vector<tuple<int,int>>,Compare3> pq3;
        priority_queue<tuple<int,int>,vector<tuple<int,int>>,Compare4> pq4;
        for(int i=0;i<n;i++)
        {
            cin>>s;
            tuple<int,int> tup=process(s);
            if(g(0,tup)>=0){
                if(g(1,tup)<0)
                    pq1.push(tup);
                else
                    pq2.push(tup);
            }
            else{
                if(g(1,tup)>=0)
                    pq3.push(tup);
                else
                    pq4.push(tup);
            }
        }
        int delta=0;
        bool can=true;
        while(!pq1.empty()){
            if(delta>=g(1,pq1.top())){
                delta=delta+g(0,pq1.top());
                pq1.pop();
            }
            else{
                can=false;
                break;
            }
        }
        if(can){
            while(!pq2.empty()){
                if(delta>=g(1,pq2.top())){
                    delta=delta+g(0,pq2.top());
                    pq2.pop();
                }
                else{
                    can=false;
                    break;
                }
            }
        }
        if(can){
            while(!pq3.empty()){
                if(delta>=g(1,pq3.top())){
                    delta=delta+g(0,pq3.top());
                    pq3.pop();
                }
                else{
                    can=false;
                    break;
                }
            }
        }
        if(can){
            while(!pq4.empty()){
                if(delta>=g(1,pq4.top())){
                    delta=delta+g(0,pq4.top());
                    pq4.pop();
                }
                else{
                    can=false;
                    break;
                }
            }
        }

        if(can&&delta==0){
            cout<<"Yes\n";
        }
        else cout<<"No\n";
    }
    return 0;
}