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

#include <algorithm>
#include <boost/multiprecision/cpp_int.hpp>
#include <cmath>
#include <deque>
#include <iostream>
#include <queue>
#include <string>
#include <vector>

using namespace std;
using ll = long long;
namespace mp = boost::multiprecision;
using mpint = mp::cpp_int; // 多倍長整数（任意精度）

/*
 * 定数
 */
const long double PI = (acos(-1));
const long double EPS = 1e-10;
const long long INF = 1e18;

/*
 * データ変換
 */
/* char -> int */
int ctoi(char c) { return (int)(c - '0'); }

/*
 * 数学的な計算
 */
/* 階乗 */
int factorial(int n) {
  int ret = 1;
  for (int i = 1; i < n + 1; ++i) {
    ret = ret * i;
  }
  return ret;
}

/* 最大公約数 */
template <typename T> T gcd(T x, T y) { return x % y == 0 ? y : gcd(y, x % y); }

/* 最小公倍数 */
template <typename T> T lcm(T a, T b) { return a * b / gcd(a, b); }

/* n個の整数の最小公倍数 */
template <typename T> T lcm_n(vector<T> &numbers) {
  T l;
  l = numbers[0];
  for (int i = 1; i < numbers.size(); ++i) {
    l = lcm(l, numbers[i]);
  }
  return l;
}

/*
 * DP向け
 */
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

/**
 * @param N 素因数分解する整数
 * @param result N = 2^3 * 3^2の場合、{{2, 3}, {3,
 * 2}}のような形式のvectorが生成される
 * @brief 2, 3,...,
 * √Nまでの整数をNで割っていき、割り切れる数と割った回数を保存することで、素因数分解を行う。
 *        O(√N)
 */
void prime_factorize(ll N, vector<pair<ll, ll>> &result) {
  for (ll a = 2; a * a <= N; ++a) {
    if (N % a != 0)
      continue;
    ll ex = 0; // 指数

    // 割れる限り割り続ける
    while (N % a == 0) {
      ++ex;
      N /= a;
    }

    result.emplace_back(pair<ll, ll>{a, ex});
  }

  // 最後に残った数
  if (N != 1)
    result.emplace_back(pair<ll, ll>{N, 1});
}

int main() {
  ll N;
  mpint ans = 1;
  cin >> N;
  vector<ll> A(N);

  for (int i = 0; i < N; ++i) {
    cin >> A[i];
    if (A[i] == 0) {
      cout << 0 << endl;
      return 0;
    }
  }

  for (int i = 0; i < N; ++i) {
    ans *= A[i];
    if (1'000'000'000'000'000'000 < ans) {
      ans = -1;
      break;
    }
  }

  cout << ans << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <boost/multiprecision/cpp_int.hpp>
#include <cmath>
#include <deque>
#include <iostream>
#include <queue>
#include <string>
#include <vector>

using namespace std;
using ll = long long;
namespace mp = boost::multiprecision;
using mpint = mp::cpp_int; // 多倍長整数（任意精度）

/*
 * 定数
 */
const long double PI = (acos(-1));
const long double EPS = 1e-10;
const long long INF = 1e18;

/*
 * データ変換
 */
/* char -> int */
int ctoi(char c) { return (int)(c - '0'); }

/*
 * 数学的な計算
 */
/* 階乗 */
int factorial(int n) {
  int ret = 1;
  for (int i = 1; i < n + 1; ++i) {
    ret = ret * i;
  }
  return ret;
}

/* 最大公約数 */
template <typename T> T gcd(T x, T y) { return x % y == 0 ? y : gcd(y, x % y); }

/* 最小公倍数 */
template <typename T> T lcm(T a, T b) { return a * b / gcd(a, b); }

/* n個の整数の最小公倍数 */
template <typename T> T lcm_n(vector<T> &numbers) {
  T l;
  l = numbers[0];
  for (int i = 1; i < numbers.size(); ++i) {
    l = lcm(l, numbers[i]);
  }
  return l;
}

/*
 * DP向け
 */
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

/**
 * @param N 素因数分解する整数
 * @param result N = 2^3 * 3^2の場合、{{2, 3}, {3,
 * 2}}のような形式のvectorが生成される
 * @brief 2, 3,...,
 * √Nまでの整数をNで割っていき、割り切れる数と割った回数を保存することで、素因数分解を行う。
 *        O(√N)
 */
void prime_factorize(ll N, vector<pair<ll, ll>> &result) {
  for (ll a = 2; a * a <= N; ++a) {
    if (N % a != 0)
      continue;
    ll ex = 0; // 指数

    // 割れる限り割り続ける
    while (N % a == 0) {
      ++ex;
      N /= a;
    }

    result.emplace_back(pair<ll, ll>{a, ex});
  }

  // 最後に残った数
  if (N != 1)
    result.emplace_back(pair<ll, ll>{N, 1});
}

int main() {
  mpint N;
  mpint ans = 1;
  cin >> N;

  for (mpint i = 0; i < N; ++i) {
    mpint tmp;
    cin >> tmp;
    ans *= tmp;
  }

  if (1'000'000'000'000'000'000 < ans)
    ans = -1;

  cout << ans << endl;

  return 0;
}