Problem p01550 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

template <int M> class Cyclic {
  using ll = long long;
  int n;
  static ll inv(ll a, ll p) {
    return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
  }

public:
  Cyclic() : n(0) { ; }
  Cyclic(int m) : n(m) {
    if (n >= M)
      n %= M;
    else if (n < 0)
      n = (n % M + M) % M;
  }
  operator int() const { return n; }
  bool operator==(const Cyclic &a) const { return n == a.n; }
  Cyclic operator+=(const Cyclic &a) {
    n += a.n;
    if (n >= M)
      n -= M;
    return *this;
  }
  Cyclic operator-=(const Cyclic &a) {
    n -= a.n;
    if (n < 0)
      n += M;
    return *this;
  }
  Cyclic operator*=(const Cyclic &a) {
    n = (ll(n) * a.n) % M;
    return *this;
  }
  Cyclic operator+(const Cyclic &a) const {
    Cyclic res = *this;
    return res += a;
  }
  Cyclic operator-(const Cyclic &a) const {
    Cyclic res = *this;
    return res -= a;
  }
  Cyclic operator*(const Cyclic &a) const {
    Cyclic res = *this;
    return res *= a;
  }
  Cyclic operator/(const Cyclic &a) const {
    return *this * Cyclic<M>(inv(a, M));
  }
  Cyclic operator^(int n) const {
    if (n == 0)
      return Cyclic(1);
    const Cyclic a = *this;
    Cyclic res = (a * a) ^ (n / 2);
    return n % 2 ? res * a : res;
  }
};

template <int M> Cyclic<M> fact(int n, bool sw = true) {
  static vector<Cyclic<M>> v1 = {1}, v2 = {1};
  if (n >= (int)v1.size()) {
    const int from = v1.size(), to = n + 1024;
    v1.reserve(to);
    v2.reserve(to);
    for (int i = from; i < to; ++i) {
      v1.push_back(v1.back() * Cyclic<M>(i));
      v2.push_back(v2.back() / Cyclic<M>(i));
    }
  }
  return sw ? v1[n] : v2[n];
}

template <int M> Cyclic<M> comb(int a, int b) {
  return fact<M>(a, true) * fact<M>(b, false) * fact<M>(a - b, false);
}

template <int M> Cyclic<M> perm(int a, int b) {
  return fact<M>(a, true) * fact<M>(a - b, false);
}

const int mod = 1000000007;
using Mod = Cyclic<mod>;

Mod pow(Mod x, int n) {
  Mod res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * x;
    x = x * x;
    n >>= 1;
  }
  return res;
}

int n;
vi a, len(6);
Mod dp[11][11][888][222];

Mod rec(int sz, int i, int keta, int used, const vi &v) {
  if (dp[sz][i][keta][used] >= 0)
    return dp[sz][i][keta][used];
  Mod res = 0;
  if (i == 5) {
    if (keta == 0) {
      Mod tmp = fact<mod>(used);
      int rem = n - 1 - used;
      REP(j, rem + 1) { res += tmp * perm<mod>(rem, j); }
    }
  } else {
    REP(j, v[i] + 1) {
      if (keta < i * j)
        break;
      res += rec(sz, i + 1, keta - i * j, used + j, v) * comb<mod>(v[i], j);
    }
  }
  return dp[sz][i][keta][used] = res;
}

Mod calc(int sz, int right) {
  vi v = len;
  if (v[sz] == 0)
    return 0;
  v[sz]--;
  Mod res = rec(sz, 1, right, 0, v);
  return res;
}

int main() {
  cin.sync_with_stdio(false);
  cout << fixed << setprecision(10);
  MS(dp, -1);
  cin >> n;
  a.resize(n);
  REP(i, n) {
    cin >> a[i];
    if (a[i] == 0)
      len[0]++;
    len[to_string(a[i]).size()]++;
  }
  Mod ans = 0;
  REP(i, n) {
    string s = to_string(a[i]);
    REP(j, 801) {
      Mod cal = calc(s.size(), j);
      REP(k, s.size()) {
        ans += Mod(s[k] - '0') * pow(Mod(10), j + s.size() - k - 1) * cal;
      }
    }
  }

  Mod zero = 0;
  MS(dp, -1);
  n--;
  len[1]--;
  REP(i, n + 1) {
    string s = to_string(a[i]);
    REP(j, 801) {
      Mod cal = calc(s.size(), j);
      REP(k, s.size()) {
        zero += Mod(s[k] - '0') * pow(Mod(10), j + s.size() - k - 1) * cal;
      }
    }
  }
  zero *= len[0];
  cout << ans - zero << endl;
  return 0;
}

Error: -6
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc


Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

template <int M> class Cyclic {
  using ll = long long;
  int n;
  static ll inv(ll a, ll p) {
    return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
  }

public:
  Cyclic() : n(0) { ; }
  Cyclic(int m) : n(m) {
    if (n >= M)
      n %= M;
    else if (n < 0)
      n = (n % M + M) % M;
  }
  operator int() const { return n; }
  bool operator==(const Cyclic &a) const { return n == a.n; }
  Cyclic operator+=(const Cyclic &a) {
    n += a.n;
    if (n >= M)
      n -= M;
    return *this;
  }
  Cyclic operator-=(const Cyclic &a) {
    n -= a.n;
    if (n < 0)
      n += M;
    return *this;
  }
  Cyclic operator*=(const Cyclic &a) {
    n = (ll(n) * a.n) % M;
    return *this;
  }
  Cyclic operator+(const Cyclic &a) const {
    Cyclic res = *this;
    return res += a;
  }
  Cyclic operator-(const Cyclic &a) const {
    Cyclic res = *this;
    return res -= a;
  }
  Cyclic operator*(const Cyclic &a) const {
    Cyclic res = *this;
    return res *= a;
  }
  Cyclic operator/(const Cyclic &a) const {
    return *this * Cyclic<M>(inv(a, M));
  }
  Cyclic operator^(int n) const {
    if (n == 0)
      return Cyclic(1);
    const Cyclic a = *this;
    Cyclic res = (a * a) ^ (n / 2);
    return n % 2 ? res * a : res;
  }
};

template <int M> Cyclic<M> fact(int n, bool sw = true) {
  static vector<Cyclic<M>> v1 = {1}, v2 = {1};
  if (n >= (int)v1.size()) {
    const int from = v1.size(), to = n + 1024;
    v1.reserve(to);
    v2.reserve(to);
    for (int i = from; i < to; ++i) {
      v1.push_back(v1.back() * Cyclic<M>(i));
      v2.push_back(v2.back() / Cyclic<M>(i));
    }
  }
  return sw ? v1[n] : v2[n];
}

template <int M> Cyclic<M> comb(int a, int b) {
  return fact<M>(a, true) * fact<M>(b, false) * fact<M>(a - b, false);
}

template <int M> Cyclic<M> perm(int a, int b) {
  return fact<M>(a, true) * fact<M>(a - b, false);
}

const int mod = 1000000007;
using Mod = Cyclic<mod>;

Mod pow(Mod x, int n) {
  Mod res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * x;
    x = x * x;
    n >>= 1;
  }
  return res;
}

int n;
vi a, len(5);
Mod dp[4][5][1111][1111];

Mod rec(int sz, int i, int keta, int used, const vi &v) {
  if (dp[sz][i][keta][used] >= 0)
    return dp[sz][i][keta][used];
  Mod res = 0;
  if (i == 5) {
    if (keta == 0) {
      Mod tmp = fact<mod>(used);
      int rem = n - 1 - used;
      REP(j, rem + 1) { res += tmp * perm<mod>(rem, j); }
    }
  } else {
    REP(j, v[i] + 1) {
      if (keta < i * j)
        break;
      res += rec(sz, i + 1, keta - i * j, used + j, v) * comb<mod>(v[i], j);
    }
  }
  return dp[sz][i][keta][used] = res;
}

Mod calc(int sz, int right) {
  vi v = len;
  if (v[sz] == 0)
    return 0;
  v[sz]--;
  Mod res = rec(sz, 1, right, 0, v);
  return res;
}

int main() {
  cin.sync_with_stdio(false);
  cout << fixed << setprecision(10);
  MS(dp, -1);
  cin >> n;
  a.resize(n);
  REP(i, n) {
    cin >> a[i];
    if (a[i] == 0)
      len[0]++;
    len[to_string(a[i]).size()]++;
  }
  Mod ans = 0;
  REP(i, n) {
    string s = to_string(a[i]);
    REP(i, 801) {
      REP(j, s.size()) {
        ans += (s[j] - '0') * pow(Mod(10), i + s.size() - j - 1) *
               calc(s.size(), i);
      }
    }
  }

  Mod zero = 0;
  MS(dp, -1);
  n--;
  len[1]--;
  REP(i, n + 1) {
    string s = to_string(a[i]);
    REP(i, 801) {
      REP(j, s.size()) {
        zero += (s[j] - '0') * pow(Mod(10), i + s.size() - j - 1) *
                calc(s.size(), i);
      }
    }
  }
  zero *= len[0];
  cout << ans - zero << endl;
  return 0;
}