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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> P;
typedef pair<int, P> P1;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define rep(i, x) for (int i = 0; i < x; i++)
#define rep1(i, x) for (int i = 1; i <= x; i++)
#define rrep(i, x) for (int i = x - 1; i >= 0; i--)
#define rrep1(i, x) for (int i = x; i > 0; i--)
#define sor(v) sort(v.begin(), v.end())
#define rev(s) reverse(s.begin(), s.end())
#define lb(vec, a) lower_bound(vec.begin(), vec.end(), a)
#define ub(vec, a) upper_bound(vec.begin(), vec.end(), a)
#define uniq(vec) vec.erase(unique(vec.begin(), vec.end()), vec.end())
#define mp1(a, b, c) P1(a, P(b, c))

const int INF = 1000000000;
const int dir_4[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
const int dir_8[8][2] = {{1, 0},  {1, 1},   {0, 1},  {-1, 1},
                         {-1, 0}, {-1, -1}, {0, -1}, {1, -1}};

ll M = 1000000007;

int digit(int x) {
  if (x == 0)
    return 0;
  if (x < 10)
    return 1;
  return digit(x / 10) + 1;
}

ll modpow(ll x, ll k) {
  if (k == 0)
    return 1;
  ll ret = modpow(x, k / 2);
  ret *= ret;
  ret %= M;
  if (k % 2 == 1) {
    ret *= x;
    ret %= M;
  }
  return ret;
}

ll inv(ll x) { return modpow(x, M - 2); }

ll C[202][202];
void C_init() {
  rep(i, 202) {
    C[i][0] = 1;
    rep1(j, i) {
      C[i][j] = C[i][j - 1] * (i - j + 1);
      C[i][j] %= M;
      C[i][j] *= inv(j);
      C[i][j] %= M;
    }
  }
}

ll F[202], G[202];
void FG_init() {
  rep(x, 202) {
    F[x] = 0;
    G[x] = 0;
    ll a = 1;
    rep(i, x + 1) {
      F[x] += a;
      G[x] += a * (i + 1);
      if (i < x) {
        a *= x - i;
        a %= M;
      }
    }
    F[x] %= M;
    G[x] %= M;
  }
}

ll H[202];
void H_init() {
  H[0] = 1;
  rep1(i, 201) {
    H[i] = H[i - 1] * i;
    H[i] %= M;
  }
}

ll N[802];
void N_init() {
  N[0] = 1;
  rep1(i, 801) {
    N[i] = N[i - 1] * 10;
    N[i] %= M;
  }
}

int main() {
  C_init();
  FG_init();
  H_init();
  N_init();
  int n;
  int a[202];
  scanf("%d", &n);
  rep(i, n) scanf("%d", &a[i]);

  int dig[202];
  rep(i, n) dig[i] = digit(a[i]);

  int c[5] = {};
  int sum[5] = {};
  rep(i, n) {
    c[dig[i]]++;
    sum[dig[i]] += a[i];
  }

  ll ret = 0;
  rep1(d, 4) {
    if (c[d] == 0)
      continue;
    c[d]--;
    int b[5];
    b[0] = 0;
    for (; b[0] <= c[0]; b[0]++) {
      b[1] = 0;
      for (; b[1] <= c[1]; b[1]++) {
        b[2] = 0;
        for (; b[2] <= c[2]; b[2]++) {
          b[3] = 0;
          for (; b[3] <= c[3]; b[3]++) {
            b[4] = 0;
            for (; b[4] <= c[4]; b[4]++) {
              ll ret_ = 1;
              rep(i, 5) {
                ret_ *= C[c[i]][b[i]];
                ret_ %= M;
              }
              ret_ *= H[b[0] + b[1] + b[2] + b[3] + b[4]];
              ret_ %= M;
              ret_ *= N[b[0] + b[1] + 2 * b[2] + 3 * b[3] + 4 * b[4]];
              ret_ %= M;
              if (c[0] - b[0] == 0) {
                ret_ *= F[c[0] + c[1] + c[2] + c[3] + c[4] - b[0] - b[1] -
                          b[2] - b[3] - b[4]];
                ret_ %= M;
              } else {
                ret_ *=
                    G[c[1] + c[2] + c[3] + c[4] - b[1] - b[2] - b[3] - b[4]];
                ret_ %= M;
              }
              ret += ret_ * sum[d];
              ret %= M;
            }
          }
        }
      }
    }
    c[d]++;
  }

  cout << ret << endl;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> P;
typedef pair<int, P> P1;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define rep(i, x) for (int i = 0; i < x; i++)
#define rep1(i, x) for (int i = 1; i <= x; i++)
#define rrep(i, x) for (int i = x - 1; i >= 0; i--)
#define rrep1(i, x) for (int i = x; i > 0; i--)
#define sor(v) sort(v.begin(), v.end())
#define rev(s) reverse(s.begin(), s.end())
#define lb(vec, a) lower_bound(vec.begin(), vec.end(), a)
#define ub(vec, a) upper_bound(vec.begin(), vec.end(), a)
#define uniq(vec) vec.erase(unique(vec.begin(), vec.end()), vec.end())
#define mp1(a, b, c) P1(a, P(b, c))

const int INF = 1000000000;
const int dir_4[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
const int dir_8[8][2] = {{1, 0},  {1, 1},   {0, 1},  {-1, 1},
                         {-1, 0}, {-1, -1}, {0, -1}, {1, -1}};

ll M = 1000000007;

int digit(int x) {
  if (x == 0)
    return 0;
  if (x < 10)
    return 1;
  return digit(x / 10) + 1;
}

ll modpow(ll x, ll k) {
  if (k == 0)
    return 1;
  ll ret = modpow(x, k / 2);
  ret *= ret;
  ret %= M;
  if (k % 2 == 1) {
    ret *= x;
    ret %= M;
  }
  return ret;
}

ll inv(ll x) { return modpow(x, M - 2); }

ll C[202][202];
void C_init() {
  rep(i, 202) {
    C[i][0] = 1;
    rep1(j, i) {
      C[i][j] = C[i][j - 1] * (i - j + 1);
      C[i][j] %= M;
      C[i][j] *= inv(j);
      C[i][j] %= M;
    }
  }
}

ll F[202], G[202];
void FG_init() {
  rep(x, 202) {
    F[x] = 0;
    G[x] = 0;
    ll a = 1;
    rep(i, x + 1) {
      F[x] += a;
      G[x] += a * (i + 1);
      if (i < x) {
        a *= x - i;
        a %= M;
      }
    }
    F[x] %= M;
    G[x] %= M;
  }
}

ll H[202];
void H_init() {
  H[0] = 1;
  rep1(i, 201) {
    H[i] = H[i - 1] * i;
    H[i] %= M;
  }
}

int main() {
  C_init();
  FG_init();
  H_init();
  int n;
  int a[202];
  scanf("%d", &n);
  rep(i, n) scanf("%d", &a[i]);

  int dig[202];
  rep(i, n) dig[i] = digit(a[i]);

  int c[5] = {};
  int sum[5] = {};
  rep(i, n) {
    c[dig[i]]++;
    sum[dig[i]] += a[i];
  }

  ll ret = 0;
  rep1(d, 4) {
    if (c[d] == 0)
      continue;
    c[d]--;
    int b[5];
    b[0] = 0;
    for (; b[0] <= c[0]; b[0]++) {
      b[1] = 0;
      for (; b[1] <= c[1]; b[1]++) {
        b[2] = 0;
        for (; b[2] <= c[2]; b[2]++) {
          b[3] = 0;
          for (; b[3] <= c[3]; b[3]++) {
            b[4] = 0;
            for (; b[4] <= c[4]; b[4]++) {
              //	printf("%d;%d %d %d %d
              //%d\\n",d,b[0],b[1],b[2],b[3],b[4]);
              ll ret_ = 1;
              rep(i, 5) {
                ret_ *= C[c[i]][b[i]];
                ret_ %= M;
              }
              //	cout << ret_ << endl;
              ret_ *= H[b[0] + b[1] + b[2] + b[3] + b[4]];
              ret_ %= M;
              //	cout << ret_ << endl;
              ret_ *= modpow(10, b[0] + b[1] + 2 * b[2] + 3 * b[3] + 4 * b[4]);
              ret_ %= M;
              //	cout << ret_ << endl;
              if (c[0] - b[0] == 0) {
                ret_ *= F[c[0] + c[1] + c[2] + c[3] + c[4] - b[0] - b[1] -
                          b[2] - b[3] - b[4]];
                ret_ %= M;
              } else {
                ret_ *=
                    G[c[1] + c[2] + c[3] + c[4] - b[1] - b[2] - b[3] - b[4]];
                ret_ %= M;
              }
              //	cout << ret_ << endl;
              ret += ret_ * sum[d];
              ret %= M;
              //	cout << ret << endl;
            }
          }
        }
      }
    }
    c[d]++;
  }

  cout << ret << endl;
}