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

#include <algorithm>
#include <bits/stdc++.h>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#define ll long long
#define ull unsigned long long
#define IO ios::sync_with_stdio(false), cin.tie(0)
#define endl '\\n'
#define main() int main()
#define ff1(i, n) for (int i = 1; i <= n; ++i)
#define ff0(i, n) for (int i = 0; i < n; ++i)
#define pi acos(-1.0)
#define ms(a, x) memset(a, x, sizeof(a))
#define lowbit(x) ((x) & (-(x)))
#define pb push_back
#define binarycount __builtin_popcount(x)
#define tr t[root]
#define lson t[root << 1]
#define rson t[root << 1 | 1]
#define fir first
#define sec second
#define debug(x) cout << x << '\\n'
#define sa(a) scanf("%d", &a)
#define sab(a, b) scanf("%d%d", &a, &b)
#define pa(a) printf("%d", a)
#define pab(a, b) printf("%d%d", a, b)
#define pii pair<int, int>
using namespace std;

#define maxn 200005
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
ll powmod(ll a, ll b) {
  ll ans = 1, pow = a % mod;
  while (b) {
    if (b & 1)
      ans = (ans * pow) % mod;
    pow = (pow * pow) % mod;
    b >>= 1;
  }
  return ans % mod;
}
ull a[maxn];
const ll maxx = 1e18;
bool flow(ull a, ull b) {
  if (ULLONG_MAX / a < b) {
    return true;
  }
  ull ans = a * b;
  if (ans > maxx) {
    return true;
  }
  return false;
}
main() {
  int n;
  cin >> n;
  int f = 1;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    if (a[i] == 0)
      f = 0;
  }
  if (f == 0) {
    cout << 0 << endl;
    return 0;
  }
  ll ans = 1;
  for (int i = 0; i < n; i++) {
    if (flow(ans, a[i])) {
      cout << "-1" << endl;
      return 0;
    }
    ans *= a[i];
  }
  cout << ans << endl;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <vector>
#define IO ios::sync_with_stdio(false), cin.tie(0)
#define ll long long
using namespace std;
struct HugeInt {
  int len;
  int num[100001];
};
HugeInt a, b, w; // w为结果
char c[100001], d[100001], t1[100001], t2[100001];
void Scan_HugeInt() { // 读入两个大整数
  if (c[0] == '-')
    strcpy(t1, c + 1);
  else
    strcpy(t1, c);
  if (d[0] == '-')
    strcpy(t2, d + 1);
  else
    strcpy(t2, d);
  a.len = strlen(t1); // strlen求串长
  b.len = strlen(t2);
  for (int i = 0; i < a.len; i++)
    a.num[a.len - i] = t1[i] - '0'; // 逆序存储
  for (int i = 0; i < b.len; i++)
    b.num[b.len - i] = t2[i] - '0';
}
void Plus() {
  w.len = max(a.len, b.len); // num每一位是0，长度取max不影响加法
  for (int i = 1; i <= w.len; i++) {
    w.num[i] += a.num[i] + b.num[i];
    w.num[i + 1] += w.num[i] / 10; // 处理进位
    w.num[i] %= 10;                // 处理当前位 保证<10
  }
  if (w.num[w.len + 1] != 0)
    w.len++; // 加法最多有可能会多出一位
}
void Minus(HugeInt x, HugeInt y) {
  w.len = x.len; // a更大
  for (int i = 1; i <= w.len; i++) {
    if (x.num[i] < y.num[i]) {
      x.num[i + 1]--; // num[i+1]减成负数也不影响
      x.num[i] += 10; // 借位
    }
    w.num[i] += x.num[i] - y.num[i];
  }
  while (w.num[w.len] == 0 && (w.len != 1))
    w.len--; // 多余的不是个位的0去掉
}
void init() {
  memset(a.num, 0, sizeof(a.num));
  memset(b.num, 0, sizeof(b.num));
  memset(w.num, 0, sizeof(w.num));
}
void Multiply() {
  init();
  Scan_HugeInt();
  int flag = 0;
  if (c[0] == '-' && d[0] == '-' || c[0] != '-' && d[0] != '-')
    flag = 0;
  else
    flag = 1;
  int x;                             // 处理每次进位的变量
  for (int i = 1; i <= a.len; i++) { // a的第i位
    x = 0;
    for (int j = 1; j <= b.len; j++) { // b的第j位
      w.num[i + j - 1] +=
          a.num[i] * b.num[j] + x; // 用 +=:结果与上次乘的结果相加
      x = w.num[i + j - 1] / 10;
      w.num[i + j - 1] %= 10; // 进位处理
    }
    w.num[i + b.len] = x; // 多出的最高位
  }
  w.len = a.len + b.len;
  while (w.num[w.len] == 0 && (w.len != 1))
    w.len--; // 多余的0
  //    if(flag) cout<<'-';
  //    for(int i=w.len; i>=1; i--) cout << w.num[i]; //倒序存储 倒序输出
  //    cout << endl;
}

void plus() {
  init();
  int flag = 0;
  Scan_HugeInt();
  if (c[0] != '-' && d[0] != '-') {
    Plus();
  } else if (c[0] != '-' && d[0] == '-') {
    if (strlen(t1) < strlen(t2)) {
      flag = 1;
      Minus(b, a);
    } else if (strlen(t1) > strlen(t2)) {
      Minus(a, b);
    } else {
      if (strcmp(t1, t2) < 0) {
        flag = 1;
        Minus(b, a);
      } else {
        Minus(a, b);
      }
    }
  } else if (c[0] == '-' && d[0] != '-') {
    if (strlen(t1) < strlen(t2)) {
      Minus(b, a);
    } else if (strlen(t1) > strlen(t2)) {
      flag = 1;
      Minus(a, b);
    } else {
      if (strcmp(t1, t2) < 0) {
        Minus(b, a);
      } else {
        flag = 1;
        Minus(a, b);
      }
    }
  } else {
    flag = 1;
    Plus();
  }
  if (flag)
    cout << '-';
  for (int i = w.len; i >= 1; i--)
    cout << w.num[i]; // 倒序存储 倒序输出
  cout << endl;
}
const int maxn = 1e5 + 5;
char aa[maxn][20];
char temp[maxn];
int main() {
  IO;
  int n;
  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> aa[i];
  }
  strcpy(c, aa[0]);
  strcpy(d, aa[1]);
  Multiply();
  for (int i = 2; i < n; ++i) {
    for (int i = w.len; i >= 1; i--) {
      temp[w.len - i] = w.num[i] + '0';
    }
    temp[w.len] = '\\0';
    strcpy(c, temp);
    strcpy(d, aa[i]);
    //        cout<<c<<endl;
    //        cout<<d<<endl;
    Multiply();
  }
  if (w.len > 19)
    cout << -1 << endl;
  else if (w.len == 19) {
    for (int i = w.len; i >= 1; i--) {
      temp[w.len - i] = w.num[i] + '0';
    }
    temp[w.len] = '\\0';
    if (strcmp(temp, "1000000000000000000") == 0)
      cout << temp << endl;
    else
      cout << -1 << endl;
  } else {
    for (int i = w.len; i >= 1; i--)
      cout << w.num[i];
    cout << endl;
  }

  return 0;
}