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

// Template {{{
#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
using namespace std;
typedef long long LL;

#ifdef LOCAL
#include "contest.h"
#else
#define dump(x)
#endif

class range {
  struct Iterator {
    int val, inc;
    int operator*() { return val; }
    bool operator!=(Iterator &rhs) { return val < rhs.val; }
    void operator++() { val += inc; }
  };
  Iterator i, n;

public:
  range(int e) : i({0, 1}), n({e, 1}) {}
  range(int b, int e) : i({b, 1}), n({e, 1}) {}
  range(int b, int e, int inc) : i({b, inc}), n({e, inc}) {}
  Iterator &begin() { return i; }
  Iterator &end() { return n; }
};

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
inline bool valid(int x, int w) { return 0 <= x && x < w; }

void iostream_init() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.setf(ios::fixed);
  cout.precision(12);
}
//}}}

const int MOD = 1e9 + 7;
void add(int &x, int y) {
  x += y;
  if (x >= MOD)
    x -= MOD;
}
int solve(vector<int> a) {
  int n = a.size();
  vector<int> d(n);
  REP(i, n) d[i] = to_string(a[i]).size();

  int ans = 0;

  const int P = 4 * n + 1;
  int ways[802][202] = {};
  ways[0][0] = 1;
  REP(i, n) {
    int nways[802][202] = {};
    REP(l, P) REP(k, i + 1) {
      add(nways[l][k], ways[l][k]);
      if (l + d[i] < P)
        add(nways[l + d[i]][k + 1], ways[l][k]);
    }
    memcpy(ways, nways, sizeof(ways));
  }
  // REP(l, P) REP(k, n+1) if(ways[l][k] > 0) {
  //     cout << "length: " << l << endl;
  //     cout << "count: " << k << endl;
  //     cout << "ways: " << ways[l][k] << endl;
  // }
  //
  //
  vector<int> fact(n + 2, 1);
  REP(i, n + 1) fact[i + 1] = (LL)fact[i] * (i + 1) % MOD;

  REP(i, n) {
    int base10 = 1;
    const int P = 4 * (n - 1) + 1;

    int dp[802][202] = {};
    REP(l, P) REP(k, n) {
      dp[l][k] = ways[l][k];
      if (l - d[i] >= 0 && k - 1 >= 0) {
        dp[l][k] -= dp[l - d[i]][k - 1];
        if (dp[l][k] < 0)
          dp[l][k] += MOD;
      }
      // if(dp[l][k] > 0) {
      //     cout << "not use: " << i << endl;
      //     cout << "length: " << l << endl;
      //     cout << "count: " << k << endl;
      //     cout << "ways: " << dp[l][k] << endl;
      // }
    }

    REP(l, P) REP(k, n) { dp[l][k] = (LL)fact[k] * dp[l][k] % MOD; }

    int dp2[802] = {};
    REP(k, n) {
      int rest = (n - 1) - k;
      LL K = 1;
      LL S = 0;
      REP(i, rest + 1) {
        S += K;
        S %= MOD;
        K = K * (rest - i) % MOD;
      }
      REP(l, P) { add(dp2[l], S * dp[l][k] % MOD); }
    }

    REP(p, P) {
      // if(dp2[p] > 0) {
      //     cout << "i: " << i << endl;
      //     cout << "10^" << p << endl;
      //     cout << "dp: " << dp2[p] << endl;
      // }

      add(ans, (LL)dp2[p] * base10 % MOD * a[i] % MOD);
      base10 = 10LL * base10 % MOD;
    }
  }
  return ans;
}
int main() {
  iostream_init();
  int n;
  while (cin >> n) {
    vector<int> a(n);
    REP(i, n) cin >> a[i];
    sort(a.begin(), a.end());
    int ans = solve(a);
    if (a[0] == 0) {
      vector<int> b;
      REP(i, n - 1) b.push_back(a[i + 1]);
      ans -= solve(b);
      if (ans < 0)
        ans += MOD;
    }
    cout << ans << endl;
  }
  return 0;
}

/* vim:set foldmethod=marker: */

Error: TLE

Fixed submission:

// Template {{{
#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
using namespace std;
typedef long long LL;

#ifdef LOCAL
#include "contest.h"
#else
#define dump(x)
#endif

class range {
  struct Iterator {
    int val, inc;
    int operator*() { return val; }
    bool operator!=(Iterator &rhs) { return val < rhs.val; }
    void operator++() { val += inc; }
  };
  Iterator i, n;

public:
  range(int e) : i({0, 1}), n({e, 1}) {}
  range(int b, int e) : i({b, 1}), n({e, 1}) {}
  range(int b, int e, int inc) : i({b, inc}), n({e, inc}) {}
  Iterator &begin() { return i; }
  Iterator &end() { return n; }
};

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
inline bool valid(int x, int w) { return 0 <= x && x < w; }

void iostream_init() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.setf(ios::fixed);
  cout.precision(12);
}
//}}}

const int MOD = 1e9 + 7;
void add(int &x, int y) {
  x += y;
  if (x >= MOD)
    x -= MOD;
}
int solve(vector<int> a) {
  int n = a.size();
  vector<int> d(n);
  REP(i, n) d[i] = to_string(a[i]).size();

  int ans = 0;

  const int P = 4 * n + 1;
  int ways[802][202] = {};
  ways[0][0] = 1;
  REP(i, n) {
    int nways[802][202] = {};
    REP(l, P) REP(k, i + 1) {
      add(nways[l][k], ways[l][k]);
      if (l + d[i] < P)
        add(nways[l + d[i]][k + 1], ways[l][k]);
    }
    memcpy(ways, nways, sizeof(ways));
  }
  // REP(l, P) REP(k, n+1) if(ways[l][k] > 0) {
  //     cout << "length: " << l << endl;
  //     cout << "count: " << k << endl;
  //     cout << "ways: " << ways[l][k] << endl;
  // }
  //
  //
  vector<int> fact(n + 2, 1);
  REP(i, n + 1) fact[i + 1] = (LL)fact[i] * (i + 1) % MOD;

  REP(i, n) {
    int base10 = 1;
    const int P = 4 * (n - 1) + 1;

    int dp[802][202] = {};
    REP(l, P) REP(k, n) {
      dp[l][k] = ways[l][k];
      if (l - d[i] >= 0 && k - 1 >= 0) {
        dp[l][k] -= dp[l - d[i]][k - 1];
        if (dp[l][k] < 0)
          dp[l][k] += MOD;
      }
      // if(dp[l][k] > 0) {
      //     cout << "not use: " << i << endl;
      //     cout << "length: " << l << endl;
      //     cout << "count: " << k << endl;
      //     cout << "ways: " << dp[l][k] << endl;
      // }
    }

    REP(l, P) REP(k, n) { dp[l][k] = (LL)fact[k] * dp[l][k] % MOD; }

    int dp2[802] = {};
    REP(k, n) {
      int rest = (n - 1) - k;
      LL K = 1;
      REP(i, rest + 1) {
        REP(l, P) add(dp2[l], K * dp[l][k] % MOD);
        K = K * (rest - i) % MOD;
      }
    }

    REP(p, P) {
      // if(dp2[p] > 0) {
      //     cout << "i: " << i << endl;
      //     cout << "10^" << p << endl;
      //     cout << "dp: " << dp2[p] << endl;
      // }

      add(ans, (LL)dp2[p] * base10 % MOD * a[i] % MOD);
      base10 = 10LL * base10 % MOD;
    }
  }
  return ans;
}
int main() {
  iostream_init();
  int n;
  while (cin >> n) {
    vector<int> a(n);
    REP(i, n) cin >> a[i];
    sort(a.begin(), a.end());
    int ans = solve(a);
    if (a[0] == 0) {
      vector<int> b;
      REP(i, n - 1) b.push_back(a[i + 1]);
      ans -= solve(b);
      if (ans < 0)
        ans += MOD;
    }
    cout << ans << endl;
  }
  return 0;
}

/* vim:set foldmethod=marker: */