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# (Mono-mcs 6.8.0.105) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using static Assistant.Input;
using static Assistant.Debug;
using System.Linq;
using Assistant;

namespace ABC167F
{
    class Program
    {
        static void Main(string[] args)
        {
            var N = RInt;
            string[] S = new string[N];
            for (int i = 0; i < N; i++)
            {
                S[i] = RString;
            }

            Pair[] pairs = new Pair[N];
            for (int i = 0; i < N; i++)
            {
                int cRcomb = 0;
                int cL = 0;
                int cLcomb = 0;
                for (int j = 0; j < S[i].Length; j++)
                {
                    if (S[i][j] == '(')
                    {
                        cRcomb++;
                    }
                    else if (S[i][j] == ')')
                    {
                        if (cLcomb - cL >= cRcomb) cL++;
                        cLcomb++;
                    }
                }
                int cR = S[i].Length - 2 * (cLcomb - cL) - cL;

                pairs[i].S = S[i];
                pairs[i].R = cR;
                pairs[i].L = cL;
            }

            var cand1 = pairs.Where(x => x.R - x.L > 0).OrderBy(x => x.L).ToArray();
            var cand2 = pairs.Where(x => x.R - x.L <= 0).OrderBy(x => -x.R).ToArray();
            pairs = cand1.Concat(cand2).ToArray();

            //string check = string.Join("", pairs.Select(x => x.S));
            //bool ans = true;
            //{
            //    int cRcomb = 0;
            //    int cLcomb = 0;
            //    for (int j = 0; j < check.Length; j++)
            //    {
            //        if (check[j] == '(')
            //        {
            //            cRcomb++;
            //        }
            //        else if (check[j] == ')')
            //        {
            //            if (cLcomb >= cRcomb) ans = false;
            //            cLcomb++;
            //        }
            //    }
            //    int cR = check.Length - 2 * cLcomb;
            //    if (cR != 0) ans = false;
            //}

            bool ans = true;
            int[] combR = new int[N + 1];
            int[] combL = new int[N + 1];
            for (int i = 0; i < N; i++)
            {
                combR[i + 1] = combR[i] + pairs[i].R;
                combL[N - 1 - i] = combL[N - i] + pairs[N - 1 - i].L;
            }
            for (int i = 0; i < N; i++)
            {
                if (pairs[i].R > combL[i + 1]) ans = false;
                if (pairs[N - 1 - i].L > combR[N - 1 - i]) ans = false;
            }
            if (pairs.Sum(x => x.R) != pairs.Sum(x => x.L)) ans = false;

            if (ans) Console.WriteLine("Yes");
            else Console.WriteLine("No");
        }

        struct Pair
        {
            public string S;
            public int R;
            public int L;
        }

    }


}

namespace Assistant
{
    static class Input
    {
        static List<string> line = new List<string>();
        static int index = 0;
        static String RNext()
        {
            if (line.Count <= index) line.AddRange(Console.ReadLine().Split());
            return line[index++];
        }
        public static int RInt => int.Parse(RNext());
        public static long RLong => long.Parse(RNext());
        public static int[] RInts => Console.ReadLine().Split().Select(int.Parse).ToArray();
        public static long[] RLongs => Console.ReadLine().Split().Select(long.Parse).ToArray();
        public static string RString => RNext();
        //以下未テスト
        public static int[] RIntsC(int c) => Enumerable.Repeat(0, c).Select(x => int.Parse(RNext())).ToArray();
        public static long[] RLongsC(int c) => Enumerable.Repeat(0, c).Select(x => long.Parse(RNext())).ToArray();
        public static char[][] RMap(int h) => Enumerable.Repeat(0, h).Select(x => Console.ReadLine().ToCharArray()).ToArray();
    }

    static class Debug
    {
        static public void Draw2D(int[,] map, int mode = 1)
        {
#if DEBUG
            int W = map.GetLength(0);
            int H = map.GetLength(1);

            int[,] map2 = new int[W + 1, H + 1];
            for (int i = 0; i < W + 1; i++)
            {
                for (int j = 0; j < H + 1; j++)
                {
                    if (i == 0 && j == 0) map2[i, j] = 0;
                    else if (i == 0) map2[i, j] = j - 1;
                    else if (j == 0) map2[i, j] = i - 1;
                    else map2[i, j] = map[i - 1, j - 1];
                }
            }

            for (int i = 0; i < W + 1; i++)
            {
                for (int j = 0; j < H + 1; j++)
                {
                    if (mode == 0) Console.Write(map2[i, j] % 10);
                    if (mode == 1) Console.Write(map2[i, j] + " ");
                }
                Console.WriteLine();
            }
            Console.WriteLine();
#endif
        }

        public static void Draw1D(int[] array, int mode = 0)
        {
#if DEBUG
            Console.WriteLine(string.Join(" ", array));
#endif
        }
    }
}