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 Scala (judge verdict: Accepted)

import scala.annotation.tailrec
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
object Main extends App {
  import scala.io.StdIn._


  val n = readInt
  val p = readLine.trim.split(' ').map(_.toInt).zipWithIndex.sortBy(_._1).map(_._2 + 1)

  println(makeString(p))
  def makeString(p: Array[Int]): String = {
    val str = Array.tabulate(p.length * 2){_ ⇒ '0'}
    @tailrec
    def sub(position: Int, pos: Int, max: Int = 0, stack: List[Int] = Nil): Boolean = {
      if (position == p.length) {
        for (i ← pos until str.length) str(i) = ')'
        true
      }
      else if (p(position) < max) false
      else {
        stack match {
          case Nil ⇒
            str(pos) = '('
            sub(position + 1, pos + 1, max, p(position)::stack)
          case h::t if h < p(position) ⇒
            str(pos) = ')'
            sub(position, pos + 1, math.max(h, max), t)
          case _ ⇒
            str(pos) = '('
            sub(position + 1, pos + 1, max, p(position)::stack)
        }
      }
    }
    if (sub(0, 0)) str.mkString
    else ":("
  }
  implicit class Scope[T](val value: T) extends AnyVal {
    @inline
    def let[A](func: T ⇒ A): A = func(value)
    @inline
    def also(func: T ⇒ Unit): T = {
      func(value)
      value
    }
  }
}