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: Accepted)

#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
vector<pii> ls, rs;
bool check() {
	int tot = 0;
	//记到上一节为止的前缀和，且之前任意前缀和>=0
	for(int i=0; i<ls.size(); i++) {
		if(tot+ls[i].first<0)
			return false;
		tot+=ls[i].second;
	}
	for(int i=0; i<rs.size(); i++) {
		if(tot+rs[i].second-rs[i].first<0)
			return false;
		tot+=rs[i].second;
		if(tot<0)
			return false;
	}
	return true;
}
bool cmp(const pii &a,const pii &b) {
	if(a.first==b.first) return a.second>b.second;
	return a.first>b.first;
}
int main() {
	//设'('的权为1，')'的权为-1
	//对于合法括号序列,任意前缀最小值一定大于等于0,且总权值和为0
	//考虑一种最优的拼接方案，如果该方案不成功，则其他方案一定不会成功
	int n;
	cin >> n;
	int sum = 0;//所有序列值总和
	for(int i=1; i<=n; i++) {
		string s;
		cin >> s;
		int cnt= 0, min_pre = 1e9;
		//对于每一个括号序列，cnt记录权值和，min_pre记录任意前缀的最小值
		for(int i=0; i<s.size(); i++) {
			if(s[i]== '(') ++cnt;
			else --cnt;
			min_pre = min(min_pre, cnt);
		}
		sum += cnt;
		if(cnt>=0) ls.push_back(make_pair(min_pre,cnt));
		//该段总和>=0，任意前缀最小值大的先放,一样的话先放总和大的
		else rs.push_back(make_pair(cnt-min_pre,cnt));
		//该段总和<0，cnt+minpre大的先放
	}
	sort(ls.begin(),ls.end(),cmp);
	sort(rs.begin(),rs.end(),cmp);
	if(sum==0&&check())
		puts("Yes");
	else
		puts("No");
	return 0;
}