Problem p02658 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#include <boost/multiprecision/cpp_int.hpp>

/* snippet: useful macros and functions */
#define ARC(i, a, b) for (Int i = (a); i < (b); ++i)
#define RC(i, n) ARC(i, 0, n)
#define ARCH(i, a, b) for (Int i = (a)-1; i >= (b); --i)
#define RCH(i, n) ARCH(i, n, 0)
#define ALL(v) v.begin(), v.end()
template <class T> T rng(const T &a, const T &b) {
  return a < b ? b - a : a - b;
}
template <class T>
void chmaxmin(T &a, const T &b, const T &(*f)(const T &, const T &)) {
  a = f(a, b);
}
#define chmax(a, b) chmaxmin(a, b, std::max)
#define chmin(a, b) chmaxmin(a, b, std::min)

#if __has_include(<experimental/iterator>)
#include <experimental/iterator>
auto debug = std::experimental::make_ostream_joiner(std::cout, " ");
#endif

/* snippet: inf struct */
#if __cplusplus >= 201703
struct {
  template <class T> constexpr operator T() {
    return std::numeric_limits<T>::max();
  }
  constexpr auto operator-();
} inf;
struct {
  template <class T> constexpr operator T() {
    return std::numeric_limits<T>::lowest();
  }
  constexpr auto operator-();
} negative_inf;
constexpr auto decltype(inf)::operator-() { return negative_inf; }
constexpr auto decltype(negative_inf)::operator-() { return inf; }
#endif

/* snippet: modint library */
#if __cpp_concepts
template <std::signed_integral T, T MOD>
#else
template <class T, T MOD>
#endif
class Modint {
  T val;

public:
  Modint(T val = 0) : val(val % MOD + (val > 0 ? 0 : MOD)) {}
  operator T() { return val; }
  Modint &operator+=(const Modint &a) {
    val += a.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }
  Modint &operator-=(const Modint &a) {
    val -= a.val;
    if (val < 0)
      val += MOD;
    return *this;
  }
  Modint &operator*=(const Modint &a) {
    val = val * a.val % MOD;
    return *this;
  }
  void inverse() {
    T x[2] = {MOD, val}, a[2] = {0, 1};
    int i;
    for (i = 0; x[!i]; i ^= 1) {
      a[i] -= x[i] / x[!i] * a[!i];
      x[i] = x[i] % x[!i];
    }
    if (!i)
      a[i] += MOD;
    val = a[i];
  }
  Modint &operator/=(Modint a) {
    a.inverse();
    return *this *= a;
  }
  friend Modint modpow(Modint a, int n) {
    Modint ret(1);
    while (n) {
      if (n & 1)
        ret *= a;
      a *= a;
      n >>= 1;
    }
    return ret;
  }
  friend Modint operator+(Modint a, const Modint &b) { return a += b; }
  friend Modint operator-(Modint a, const Modint &b) { return a -= b; }
  friend Modint operator*(Modint a, const Modint &b) { return a *= b; }
  friend Modint operator/(Modint a, const Modint &b) { return a /= b; }
  friend std::ostream &operator<<(std::ostream &os, const Modint &a) {
    return os << a.val;
  }
};

/* push n numbers and get i-th min */
/* to get min and 2nd min, declare K_th_min<T, 2> and use get<0>(), get<1>() */
#if __cplusplus >= 201703
template <class T, std::size_t K> class K_th_min {
  friend class K_th_min<T, K + 1>;
  T val;
  K_th_min<T, K - 1> lower;
  void push_(T &x) {
    lower.push_(x);
    if (val > x)
      std::swap(val, x);
  }

public:
  K_th_min() : val(std::numeric_limits<T>::max()) {}
  void push(T x) { push_(x); }
  template <std::size_t I> T get() {
    if constexpr (I == K - 1)
      return val;
    else
      return lower.template get<I>();
  }
};
template <class T> class K_th_min<T, 0> {
  friend class K_th_min<T, 1>;
  void push_(T &) {}

public:
  K_th_min() {}
  void push(T) {}
};
#endif

/* snippet: using declarations */
using Int = boost::multiprecision::cpp_int;
using std::cin;
using std::cout;
using std::endl;
using Mint = Modint<long long, 1000000007>;

int main() {
  Int n;
  cin >> n;
  Int ans = 1;
  RC(i, n) {
    Int a;
    cin >> a;
    if (a == 0) {
      cout << 0 << endl;
      return 0;
    }
    ans *= a;
    if (ans > 1000000000000000000) {
      ans = 0;
    }
  }
  if (ans == 0) {
    cout << -1 << endl;
  } else {
    cout << ans << endl;
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#include <boost/multiprecision/cpp_int.hpp>

/* snippet: useful macros and functions */
#define ARC(i, a, b) for (Int i = (a); i < (b); ++i)
#define RC(i, n) ARC(i, 0, n)
#define ARCH(i, a, b) for (Int i = (a)-1; i >= (b); --i)
#define RCH(i, n) ARCH(i, n, 0)
#define ALL(v) v.begin(), v.end()
template <class T> T rng(const T &a, const T &b) {
  return a < b ? b - a : a - b;
}
template <class T>
void chmaxmin(T &a, const T &b, const T &(*f)(const T &, const T &)) {
  a = f(a, b);
}
#define chmax(a, b) chmaxmin(a, b, std::max)
#define chmin(a, b) chmaxmin(a, b, std::min)

#if __has_include(<experimental/iterator>)
#include <experimental/iterator>
auto debug = std::experimental::make_ostream_joiner(std::cout, " ");
#endif

/* snippet: inf struct */
#if __cplusplus >= 201703
struct {
  template <class T> constexpr operator T() {
    return std::numeric_limits<T>::max();
  }
  constexpr auto operator-();
} inf;
struct {
  template <class T> constexpr operator T() {
    return std::numeric_limits<T>::lowest();
  }
  constexpr auto operator-();
} negative_inf;
constexpr auto decltype(inf)::operator-() { return negative_inf; }
constexpr auto decltype(negative_inf)::operator-() { return inf; }
#endif

/* snippet: modint library */
#if __cpp_concepts
template <std::signed_integral T, T MOD>
#else
template <class T, T MOD>
#endif
class Modint {
  T val;

public:
  Modint(T val = 0) : val(val % MOD + (val > 0 ? 0 : MOD)) {}
  operator T() { return val; }
  Modint &operator+=(const Modint &a) {
    val += a.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }
  Modint &operator-=(const Modint &a) {
    val -= a.val;
    if (val < 0)
      val += MOD;
    return *this;
  }
  Modint &operator*=(const Modint &a) {
    val = val * a.val % MOD;
    return *this;
  }
  void inverse() {
    T x[2] = {MOD, val}, a[2] = {0, 1};
    int i;
    for (i = 0; x[!i]; i ^= 1) {
      a[i] -= x[i] / x[!i] * a[!i];
      x[i] = x[i] % x[!i];
    }
    if (!i)
      a[i] += MOD;
    val = a[i];
  }
  Modint &operator/=(Modint a) {
    a.inverse();
    return *this *= a;
  }
  friend Modint modpow(Modint a, int n) {
    Modint ret(1);
    while (n) {
      if (n & 1)
        ret *= a;
      a *= a;
      n >>= 1;
    }
    return ret;
  }
  friend Modint operator+(Modint a, const Modint &b) { return a += b; }
  friend Modint operator-(Modint a, const Modint &b) { return a -= b; }
  friend Modint operator*(Modint a, const Modint &b) { return a *= b; }
  friend Modint operator/(Modint a, const Modint &b) { return a /= b; }
  friend std::ostream &operator<<(std::ostream &os, const Modint &a) {
    return os << a.val;
  }
};

/* push n numbers and get i-th min */
/* to get min and 2nd min, declare K_th_min<T, 2> and use get<0>(), get<1>() */
#if __cplusplus >= 201703
template <class T, std::size_t K> class K_th_min {
  friend class K_th_min<T, K + 1>;
  T val;
  K_th_min<T, K - 1> lower;
  void push_(T &x) {
    lower.push_(x);
    if (val > x)
      std::swap(val, x);
  }

public:
  K_th_min() : val(std::numeric_limits<T>::max()) {}
  void push(T x) { push_(x); }
  template <std::size_t I> T get() {
    if constexpr (I == K - 1)
      return val;
    else
      return lower.template get<I>();
  }
};
template <class T> class K_th_min<T, 0> {
  friend class K_th_min<T, 1>;
  void push_(T &) {}

public:
  K_th_min() {}
  void push(T) {}
};
#endif

/* snippet: using declarations */
using Int = boost::multiprecision::cpp_int;
using std::cin;
using std::cout;
using std::endl;
using Mint = Modint<long long, 1000000007>;

int main() {
  Int n;
  cin >> n;
  Int ans = 1;
  RC(i, n) {
    Int a;
    cin >> a;
    ans *= a;
  }
  if (ans > 1000000000000000000) {
    cout << -1 << endl;
  } else {
    cout << ans << endl;
  }
}