Problem:
Score : 200 points

Problem Statement

Given N integers A_1, ..., A_N, compute A_1 \times ... \times A_N.

However, if the result exceeds 10^{18}, print -1 instead.

Constraints

2 \leq N \leq 10^5

0 \leq A_i \leq 10^{18}

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 ... A_N

Output

Print the value A_1 \times ... \times A_N as an integer, or -1 if the value exceeds 10^{18}.

Sample Input 1

2
1000000000 1000000000

Sample Output 1

1000000000000000000

We have 1000000000 \times 1000000000 = 1000000000000000000.

Sample Input 2

3
101 9901 999999000001

Sample Output 2

-1

We have 101 \times 9901 \times 999999000001 = 1000000000000000001, which exceeds 10^{18}, so we should print -1 instead.

Sample Input 3

31
4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9 5 0

Sample Output 3

0

Solution in Scala (2.13.1) (judge verdict: Accepted)

import scala.annotation.tailrec
import scala.io.StdIn.{readInt, readLine}

object Main extends App {
  import Implicits.ListOps

  val Zero = BigInt(0)
  val VMax = BigInt(1_000_000_000_000_000_000L)

  val n  = readInt()
  val xs = readLine().split(' ').view.map { BigInt(_) }.toList

  val (s, isOver) =
    if (xs.contains(Zero)) (Zero, false)
    else {
      val (s, ys) = xs.reduceWhile { _ * _ } { _ <= VMax }
      (s, ys.nonEmpty)
    }

  println(if (isOver) -1 else s)
}

/**
  * 拡張メソッド群
  */
object Implicits {

  /**
    * List用拡張メソッド
    * @param self 自身を表すList
    * @tparam A 要素の型
    */
  implicit class ListOps[A](self: List[A]) {

    /**
      * 条件を満たし続ける限りListの要素を集約する
      * 条件を満たさなくなった時点で処理を打切る
      * @param z 初期値
      * @param op 集約演算用の関数
      * @param p 処理を続けるかどうかを判定する述語関数
      * @return 条件を満たさなくなった時点のそれまでの計算結果と残りのリストListの組
      */
    def foldWhile[B](z: B)(op: (B, A) => B)(p: B => Boolean): (B, List[A]) = {

      @tailrec
      def loop(accum: B, zs: List[A]): (B, List[A]) = zs match {
        case Nil => (accum, Nil)
        case x :: xs =>
          val s = op(accum, x)
          if (p(s)) loop(s, xs) else (accum, zs)
      }

      loop(z, self)
    }

    /**
      * foldWhileの初期値を自身の先頭要素にした関数
      */
    def reduceWhile(op: (A, A) => A)(p: A => Boolean): (A, List[A]) = self match {
      case Nil     => throw new UnsupportedOperationException("empty list")
      case x :: xs => xs.foldWhile(x)(op)(p)
    }
  }
}