QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#116711 | #6522. Digit Mode | ITMO_pengzoo# | AC ✓ | 366ms | 33176kb | C++20 | 9.0kb | 2023-06-29 21:07:16 | 2023-06-29 21:07:18 |
Judging History
answer
// Nikita Golikov, 2023
#include <bits/stdc++.h>
using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
#ifdef GOLIKOV
#include "/Users/golikovnik/contests/debug.h"
#else
#define debug(...) ;
#endif
template <class A, class B>
bool smin(A& x, B&& y) {
if (y < x) {
x = y;
return true;
}
return false;
}
template <class A, class B>
bool smax(A& x, B&& y) {
if (x < y) {
x = y;
return true;
}
return false;
}
// by https://codeforces.com/profile/Nyaan
// example submission:
// https://codeforces.com/contest/1603/submission/133688639
template <uint32_t mod>
struct LazyMontgomeryModInt {
using mint = LazyMontgomeryModInt;
using i32 = int32_t;
using u32 = uint32_t;
using u64 = uint64_t;
static constexpr u32 get_r() {
u32 ret = mod;
for (i32 i = 0; i < 4; ++i) ret *= 2 - mod * ret;
return ret;
}
static constexpr u32 r = get_r();
static constexpr u32 n2 = -u64(mod) % mod;
static_assert(r * mod == 1, "invalid, r * mod != 1");
static_assert(mod < (1 << 30), "invalid, mod >= 2 ^ 30");
static_assert((mod & 1) == 1, "invalid, mod % 2 == 0");
u32 a;
constexpr LazyMontgomeryModInt() : a(0) {}
constexpr LazyMontgomeryModInt(const int64_t &b)
: a(reduce(u64(b % mod + mod) * n2)){};
static constexpr u32 reduce(const u64 &b) {
return (b + u64(u32(b) * u32(-r)) * mod) >> 32;
}
constexpr mint &operator+=(const mint &b) {
if (i32(a += b.a - 2 * mod) < 0) a += 2 * mod;
return *this;
}
constexpr mint &operator++() {
return *this += 1;
}
constexpr mint operator++(int) {
auto ret = *this;
*this += 1;
return ret;
}
constexpr mint &operator-=(const mint &b) {
if (i32(a -= b.a) < 0) a += 2 * mod;
return *this;
}
constexpr mint &operator--() {
return *this -= 1;
}
constexpr mint operator--(int) {
auto ret = *this;
*this -= 1;
return ret;
}
constexpr mint &operator*=(const mint &b) {
a = reduce(u64(a) * b.a);
return *this;
}
constexpr mint &operator/=(const mint &b) {
*this *= b.inv();
return *this;
}
constexpr friend mint operator+(mint a, const mint &b) { return a += b; }
constexpr friend mint operator-(mint a, const mint &b) { return a -= b; }
constexpr friend mint operator*(mint a, const mint &b) { return a *= b; }
constexpr friend mint operator/(mint a, const mint &b) { return a /= b; }
constexpr friend bool operator==(mint const& a, const mint &b) {
return (a.a >= mod ? a.a - mod : a.a) == (b.a >= mod ? b.a - mod : b.a);
}
constexpr friend bool operator!=(mint const& a, const mint &b) {
return (a.a >= mod ? a.a - mod : a.a) != (b.a >= mod ? b.a - mod : b.a);
}
constexpr friend bool operator<(mint const& a, const mint &b) {
return (a.a >= mod ? a.a - mod : a.a) < (b.a >= mod ? b.a - mod : b.a);
}
constexpr mint operator-() const { return mint() - mint(*this); }
constexpr mint power(u64 n) const {
mint ret(1), mul(*this);
while (n > 0) {
if (n & 1) ret *= mul;
mul *= mul;
n >>= 1;
}
return ret;
}
constexpr mint inv() const { return power(mod - 2); }
friend ostream &operator<<(ostream &os, const mint &b) {
return os << b.get();
}
friend istream &operator>>(istream &is, mint &b) {
int64_t t;
is >> t;
b = LazyMontgomeryModInt<mod>(t);
return (is);
}
constexpr u32 get() const {
u32 ret = reduce(a);
return ret >= mod ? ret - mod : ret;
}
constexpr explicit operator int() const {
return int(get());
}
constexpr explicit operator bool() const {
return bool(get());
}
static constexpr u32 get_mod() { return mod; }
};
template <typename T>
struct Binomial {
vector<T> f, g, h;
Binomial(int CMAX = 0) : f(1, T(1)), g(1, T(1)), h(1, T(1)) {
extend(CMAX + 1);
}
void extend(int m) {
int n = f.size();
if (n >= m) {
return;
}
f.resize(m);
g.resize(m);
h.resize(m);
for (int i = n; i < m; i++) f[i] = f[i - 1] * T(i);
g[m - 1] = f[m - 1].inv();
h[m - 1] = g[m - 1] * f[m - 2];
for (int i = m - 2; i >= n; i--) {
g[i] = g[i + 1] * T(i + 1);
h[i] = g[i] * f[i - 1];
}
}
void extend() {
extend(2 * f.size());
}
T fact(int i) {
if (i < 0) return T(0);
while (i >= (int)f.size()) extend();
return f[i];
}
T ifact(int i) {
if (i < 0) return T(0);
while (i >= (int)g.size()) extend();
return g[i];
}
T inv(int i) {
if (i < 0) return -inv(-i);
while (i >= (int)h.size()) extend();
return h[i];
}
T C(int n, int r) {
if (n < 0 || n < r || r < 0) return T(0);
return fact(n) * ifact(n - r) * ifact(r);
}
inline T operator()(int n, int r) { return C(n, r); }
template <typename I>
T multinomial(const vector<I>& r) {
static_assert(is_integral<I>::value == true);
int n = 0;
for (auto& x : r) {
if(x < 0) return T(0);
n += x;
}
T res = fact(n);
for (auto& x : r) res *= ifact(x);
return res;
}
template <typename I>
T operator()(const vector<I>& r) {
return multinomial(r);
}
T C_naive(int n, int r) {
if (n < 0 || n < r || r < 0) return T(0);
T ret = T(1);
r = min(r, n - r);
for (int i = 1; i <= r; ++i) ret *= inv(i) * (n--);
return ret;
}
T A(int n, int r) {
if (n < 0 || n < r || r < 0) return T(0);
return fact(n) * ifact(n - r);
}
T CR(int n, int r) {
if (n < 0 || r < 0) return T(0);
return r == 0 ? 1 : C(n + r - 1, r);
}
};
// int const MOD = 998244353;
int const MOD = int(1e9 + 7);
using mint = LazyMontgomeryModInt<MOD>;
Binomial<mint> C;
vector<mint> mkpow(mint base, int mx) {
vector<mint> res(mx + 1);
res[0] = 1;
for (int i = 1; i <= mx; ++i) {
res[i] = res[i - 1] * base;
}
return res;
}
int const MAX = 51;
mint dp[11][MAX][MAX][10];
int const MASIZE = 7;
int const MA = int(1e6);
mint precalc[MA][MAX];
bool havePrecalc[MA][MAX];
mint CC[MAX][MAX];
void solveTest() {
string r; cin >> r;
int p = int(r.size()) - 1;
while (p >= 0 && r[p] == '9') {
r[p--] = '0';
}
if (p < 0) {
r.insert(r.begin(), '1');
} else {
r[p]++;
}
auto solve = [&](string upto) {
mint res = 0;
auto go = [&](string pref, int left) {
if (pref.size() < MASIZE && havePrecalc[atoi(pref.c_str())][left]) {
res += precalc[atoi(pref.c_str())][left];
return;
}
int cnt[10]{};
for (char ch : pref) {
cnt[ch - '0']++;
}
memset(dp, 0, sizeof dp);
dp[0][0][0][0] = 1;
for (int d = 0; d < 10; ++d) {
for (int x = 0; x <= left; ++x) {
for (int c = 0; c < MAX; ++c) {
for (int bd = 0; bd <= d; ++bd) {
auto val = dp[d][x][c][bd];
if (!val) {
continue;
}
for (int t = max(0, c - cnt[d]); t + x <= left; ++t) {
dp[d + 1][t + x][cnt[d] + t][d] += val * CC[t + x][x];
}
for (int t = 0; t < c - cnt[d] && t + x <= left; ++t) {
dp[d + 1][t + x][c][bd] += val * CC[t + x][x];
}
}
}
}
}
mint here = 0;
for (int i = 0; i < MAX; ++i) {
for (int d = 0; d < 10; ++d) {
here += dp[10][left][i][d] * d;
}
}
res += here;
if (pref.size() < MASIZE) {
precalc[atoi(pref.c_str())][left] = here;
havePrecalc[atoi(pref.c_str())][left] = true;
}
};
auto s = upto;
int len = int(s.size());
vector<mint> pw(len + 1);
pw[0] = 1;
for (int i = 1; i <= len; ++i) {
pw[i] = pw[i - 1] * 10;
}
string pref;
for (int i = 0; i < len; ++i) {
int here = s[i] - '0';
for (int d = !i; d < here; ++d) {
pref.push_back(char('0') + d);
go(pref, len - i - 1);
pref.pop_back();
}
if (i > 0) {
for (int d = 1; d < 10; ++d) {
go(to_string(d), len - i - 1);
}
}
pref.push_back(char('0') + here);
}
return res;
};
cout << solve(r) << '\n';
}
int main() {
#ifdef GOLIKOV
assert(freopen("in", "rt", stdin));
auto _clock_start = chrono::high_resolution_clock::now();
#endif
ios::sync_with_stdio(false);
cin.tie(nullptr);
for (int i = 0; i < MAX; ++i) {
CC[i][0] = 1;
for (int j = 1; j <= i; ++j) {
CC[i][j] = CC[i - 1][j - 1] + CC[i - 1][j];
}
}
int tests_;
cin >> tests_;
for (int tt_ = 1; tt_ <= tests_; ++tt_) {
solveTest();
}
#ifdef GOLIKOV
cerr << "Executed in " << chrono::duration_cast<chrono::milliseconds>(
chrono::high_resolution_clock::now()
- _clock_start).count() << "ms." << endl;
#endif
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 4ms
memory: 6588kb
input:
5 9 99 999 99999 999999
output:
45 615 6570 597600 5689830
result:
ok 5 number(s): "45 615 6570 597600 5689830"
Test #2:
score: 0
Accepted
time: 1ms
memory: 6688kb
input:
34 7 48 8 76 1 97 7 5 7 7 2 89 9 4 84 46 6 73 86 78 5 3 8 9 31 24 78 7 11 45 2 65 88 6
output:
28 236 36 420 1 597 28 15 28 28 3 525 45 10 484 221 21 399 500 435 15 6 36 45 145 104 435 28 47 215 3 341 516 21
result:
ok 34 numbers
Test #3:
score: 0
Accepted
time: 5ms
memory: 6636kb
input:
16 935 888 429 370 499 881 285 162 178 948 205 858 573 249 773 615
output:
6009 5618 2456 2078 2905 5562 1603 887 993 6121 1174 5378 3333 1374 4724 3631
result:
ok 16 numbers
Test #4:
score: 0
Accepted
time: 3ms
memory: 8816kb
input:
12 1242 9985 6469 9310 4191 9497 3166 3495 9711 9698 4137 2257
output:
7292 63531 37910 58047 23987 59479 18076 19675 61184 61086 23672 12913
result:
ok 12 numbers
Test #5:
score: 0
Accepted
time: 0ms
memory: 18464kb
input:
10 61195 72739 10164 79164 57851 12326 29132 55992 67377 13873
output:
337575 408170 63792 450686 316513 70493 157773 305011 374163 77954
result:
ok 10 numbers
Test #6:
score: 0
Accepted
time: 9ms
memory: 33176kb
input:
8 529983 127270 421121 291729 461233 695056 365028 271160
output:
2744573 687141 2160067 1500426 2359204 3705475 1851172 1381981
result:
ok 8 numbers
Test #7:
score: 0
Accepted
time: 7ms
memory: 25092kb
input:
7 7934351 8474057 1287369 5845624 7796773 5805755 7349121
output:
42465725 45668947 6716401 30094426 41554096 29861098 38756757
result:
ok 7 numbers
Test #8:
score: 0
Accepted
time: 27ms
memory: 21008kb
input:
3 5014252832385738 8762796162648653 919997886706385
output:
892033338 297722019 462512414
result:
ok 3 number(s): "892033338 297722019 462512414"
Test #9:
score: 0
Accepted
time: 46ms
memory: 16372kb
input:
2 775701797726112292362823101 75927988177061355614
output:
371275551 566830847
result:
ok 2 number(s): "371275551 566830847"
Test #10:
score: 0
Accepted
time: 278ms
memory: 12400kb
input:
1 65760982925996012426370962570581226245366145016666
output:
661063035
result:
ok 1 number(s): "661063035"
Test #11:
score: 0
Accepted
time: 285ms
memory: 12748kb
input:
1 62597468169905757754175023836706426691470692832490
output:
9983261
result:
ok 1 number(s): "9983261"
Test #12:
score: 0
Accepted
time: 291ms
memory: 14452kb
input:
1 78912847369504885593964702297317051208901751786824
output:
817123221
result:
ok 1 number(s): "817123221"
Test #13:
score: 0
Accepted
time: 186ms
memory: 6624kb
input:
1 99999999999999999999999999999999999999999999999999
output:
25251932
result:
ok 1 number(s): "25251932"
Test #14:
score: 0
Accepted
time: 132ms
memory: 8516kb
input:
1 999999999999999999999999999999999999999999999
output:
439421821
result:
ok 1 number(s): "439421821"
Test #15:
score: 0
Accepted
time: 87ms
memory: 7960kb
input:
1 9999999999999999999999999999999999999999
output:
387537647
result:
ok 1 number(s): "387537647"
Test #16:
score: 0
Accepted
time: 360ms
memory: 10704kb
input:
1 99999999999999999999999998889999898988888889998888
output:
909431898
result:
ok 1 number(s): "909431898"
Test #17:
score: 0
Accepted
time: 366ms
memory: 12776kb
input:
1 99999999999999999999999998989899988889989889999888
output:
289727470
result:
ok 1 number(s): "289727470"
Test #18:
score: 0
Accepted
time: 365ms
memory: 12588kb
input:
1 99999999999999999999999998998988898888898889898999
output:
962896416
result:
ok 1 number(s): "962896416"
Test #19:
score: 0
Accepted
time: 177ms
memory: 10764kb
input:
1 9999999999999999999989988898888989888899
output:
995903330
result:
ok 1 number(s): "995903330"
Test #20:
score: 0
Accepted
time: 180ms
memory: 10768kb
input:
1 9999999999999999999989999889889998998898
output:
385460258
result:
ok 1 number(s): "385460258"
Test #21:
score: 0
Accepted
time: 185ms
memory: 6592kb
input:
1 99999999999999999999999999999999999999999999999999
output:
25251932
result:
ok 1 number(s): "25251932"