Problem:
B: 括弧を語る数 / Parentheses Number

問題

以下のように 正しい括弧列 を定めます。

空文字列は正しい括弧列である

正しい括弧列 S に対して ( S ) は正しい括弧列である

正しい括弧列 S, T に対して ST は正しい括弧列である

ここで、正しい括弧列に対して以下のような規則で順列を対応付けます。

i 番目の閉じ括弧が j 番目の開き括弧に対応しているとき、 数列の i 番目の値は j である。

長さ n の順列 P = ( p_1, p_2, $\ldots$, p_n ) が与えられるので、 それに対応する括弧列を復元してください。

ただし、順列に対応する括弧列が存在しない場合は :( を出力してください。

入力形式

n
p_1 p_2 $\ldots$ p_n

1 行目に順列の項数 n が与えられる。

2 行目に順列 p_1, p_2, $\ldots$, p_i, $\ldots$, p_n が空白区切りで与えられる。

制約

1 \leq n \leq 10^5

1 \leq p_i \leq n

入力は全て整数である。

P = ( p_1, p_2, $\ldots$, p_n ) は順列である。

出力形式

順列に対応する括弧列を出力してください。

そのような括弧列が存在しない場合は :( を出力してください。

入力例1

2
2 1

出力例1

(())

入力例2

10
1 2 3 4 5 6 7 8 9 10

出力例2

()()()()()()()()()()

入力例3

3
3 1 2

出力例3

:(

Solution in C++14 (judge verdict: Accepted)

#include <iostream>
#include <string>
#include <utility>
#include <vector>
using namespace std;
int p[100010];
vector<int> v;
string s;
int main(){
	int i,n;
	cin >> n;
	for(i=0;i<n;i++){
		cin >> p[i];
	}
	v.push_back(1); s.push_back('(');
	int cnt = 2;
	for(i=0;i<n;i++){
		if(i!=0 && p[i] - p[i-1]==-1){
			v.pop_back();
			s.push_back(')');
		}else{
			while(1){
				int x = v.back();
				if(x<p[i]){
					v.push_back(cnt); cnt++;
					s.push_back('(');
				}else if(x==p[i]){
					v.pop_back(); s.push_back(')');
					break;
				}else{
					cout << ":(" << endl;
					return 0;
				}
			}
		}
	}
	cout << s << endl;
}