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

#include <bits/stdc++.h>
using namespace std;

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define all(c) begin(c), end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

constexpr int INF = 1e9;
constexpr int MOD = 1e9 + 7;
constexpr double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename Ostream, typename Container>
Ostream &operator<<(Ostream &os, const Container &c) {
  os << '[';
  for (auto i = begin(c); i != end(c); ++i)
    os << (i == begin(c) ? "" : " ") << *i;
  return os << ']';
}

inline int ncr(int n, int r) {
  static int memo[201][201];
  if (memo[n][r])
    return memo[n][r];
  if (r == 0 || r == n)
    return 1;
  return memo[n][r] = (ncr(n - 1, r - 1) + ncr(n - 1, r)) % MOD;
}
inline int npr(int n, int r) {
  static int memo[201][201];
  if (memo[n][r])
    return memo[n][r];
  if (r == 0)
    return 1;
  return memo[n][r] = n * (ll)npr(n - 1, r - 1) % MOD;
}

int solve(vi as) {
  array<int, 801> ts = {1}; // ts[i]=10^i mod m
  repi(i, 1, ts.size()) ts[i] = (ll)ts[i - 1] * 10 % MOD;
  array<int, 201> fs = {1}; // fs[i]=i! mod m
  repi(i, 1, fs.size()) fs[i] = (ll)fs[i - 1] * i % MOD;

  sort(all(as));

  int n = as.size();
  vi ls(n);
  rep(i, n) {
    if (as[i] == 0)
      ls[i] = 1;
    for (int x = as[i]; x; x /= 10)
      ls[i]++;
  }
  array<int, 5> hist = {0};
  rep(i, n) hist[ls[i]]++;

  array<int, 5> bs, es;
  repi(i, 1, 5) {
    bs[i] = lower_bound(all(ls), i) - begin(ls);
    es[i] = upper_bound(all(ls), i) - begin(ls);
  }

  ll res = 0;
  rep(c1, hist[1] + 1) rep(c2, hist[2] + 1) rep(c3, hist[3] + 1)
      rep(c4, hist[4] + 1) {
    array<int, 5> uses = {-1, c1, c2, c3, c4};
    const int locnt = c1 + c2 + c3 + c4;
    const int lolen = c1 + 2 * c2 + 3 * c3 + 4 * c4;
    repi(len, 1, 5) if (uses[len] < hist[len]) {
      hist[len]--;
      int lopat = fs[locnt];
      repi(j, 1, 5) lopat = (lopat * (ll)ncr(hist[j], uses[j])) % MOD;
      hist[len]++;
      ll hipat = 0;
      rep(j, n - locnt) hipat += npr(n - locnt - 1, j);
      hipat %= MOD;
      ll coeff = (ll)ts[lolen] * lopat % MOD * hipat % MOD;
      repi(j, bs[len], es[len]) res += as[j] * coeff % MOD;
      res %= MOD;
    }
  }
  return res;
}

int main() {
  for (int n; cin >> n && n;) {
    vi as(n);
    rep(i, n) cin >> as[i];

    int res = solve(as);
    if (count(all(as), 0)) {
      as.erase(find(all(as), 0));
      res = (res - solve(as) + MOD) % MOD;
    }
    cout << res << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define all(c) begin(c), end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

constexpr int INF = 1e9;
constexpr int MOD = 1e9 + 7;
constexpr double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename Ostream, typename Container>
Ostream &operator<<(Ostream &os, const Container &c) {
  os << '[';
  for (auto i = begin(c); i != end(c); ++i)
    os << (i == begin(c) ? "" : " ") << *i;
  return os << ']';
}

inline int ncr(int n, int r) {
  static int memo[201][201];
  if (memo[n][r])
    return memo[n][r];
  if (r == 0 || r == n)
    return 1;
  return memo[n][r] = (ncr(n - 1, r - 1) + ncr(n - 1, r)) % MOD;
}
inline int npr(int n, int r) {
  static int memo[201][201];
  if (memo[n][r])
    return memo[n][r];
  if (r == 0)
    return 1;
  return memo[n][r] = n * (ll)npr(n - 1, r - 1) % MOD;
}

int solve(vi as) {
  array<int, 801> tinvs = {1}; // tinvs[i]=10^i mod m
  repi(i, 1, tinvs.size()) tinvs[i] = (ll)tinvs[i - 1] * 10 % MOD;
  array<int, 201> finvs = {1}; // finvs[i]=i! mod m
  repi(i, 1, finvs.size()) finvs[i] = (ll)finvs[i - 1] * i % MOD;

  sort(all(as));

  int n = as.size();
  vi ls(n);
  rep(i, n) {
    if (as[i] == 0)
      ls[i] = 1;
    for (int x = as[i]; x; x /= 10)
      ls[i]++;
  }
  array<int, 5> hist = {0};
  rep(i, n) hist[ls[i]]++;

  array<int, 5> bs, es;
  repi(i, 1, 5) {
    bs[i] = lower_bound(all(ls), i) - begin(ls);
    es[i] = upper_bound(all(ls), i) - begin(ls);
  }

  int res = 0;
  rep(c1, hist[1] + 1) rep(c2, hist[2] + 1) rep(c3, hist[3] + 1)
      rep(c4, hist[4] + 1) {
    array<int, 5> uses = {-1, c1, c2, c3, c4};
    int locnt = c1 + c2 + c3 + c4;
    int lolen = c1 + 2 * c2 + 3 * c3 + 4 * c4;
    repi(len, 1, 5) if (uses[len] < hist[len]) {
      hist[len]--;
      int lopat = finvs[locnt];
      repi(j, 1, 5) lopat = (lopat * (ll)ncr(hist[j], uses[j])) % MOD;
      hist[len]++;
      int hipat = 0;
      // rep(j,n-locnt) hipat=(hipat+(ll)ncr(n-locnt-1,j)*finvs[j]%MOD)%MOD;
      rep(j, n - locnt) if ((hipat += npr(n - locnt - 1, j)) >= MOD) hipat -=
          MOD;
      repi(j, bs[len], es[len]) {
        int val = (ll)as[j] * tinvs[lolen] % MOD * lopat % MOD * hipat % MOD;
        //(res+=val)%=MOD;
        if ((res += val) >= MOD)
          res -= MOD;
      }
    }
  }
  return res;
}

int main() {
  for (int n; cin >> n && n;) {
    vi as(n);
    rep(i, n) cin >> as[i];

    int res = solve(as);
    if (count(all(as), 0)) {
      as.erase(find(all(as), 0));
      res = (res - solve(as) + MOD) % MOD;
    }
    cout << res << endl;
  }
}