QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#188574 | #5482. Birthday Gift | Gamal74# | WA | 1490ms | 18596kb | C++20 | 5.2kb | 2023-09-26 01:51:28 | 2023-09-26 01:51:29 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
#define endl '\n'
void Gamal() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
#ifdef Clion
freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
#endif
}
int dx[] = {+0, +0, -1, +1, +1, +1, -1, -1};
int dy[] = {-1, +1, +0, +0, +1, -1, +1, -1};
const double EPS = 1e-9;
const ll OO = 0X3F3F3F3F3F3F3F3F;
const int N = 300 + 5, INF = INT_MAX, MOD = 1e9 + 7, LOG = 20;
#define rep(aa, bb, cc) for(int aa = bb; aa < cc;aa++)
#define sz(a) (int)a.size()
typedef complex<double> C;
typedef vector<double> vd;
void fft(vector<C> &a) {
int n = sz(a), L = 31 - __builtin_clz(n);
static vector<complex<double>> R(2, 1);
static vector<C> rt(2, 1); // (^ 10% faster if double)
for (static int k = 2; k < n; k *= 2) {
R.resize(n);
rt.resize(n);
auto x = polar(1.0, acos(-1.0) / k);
rep(i, k, 2 * k) rt[i] = R[i] = i & 1 ? R[i / 2] * x : R[i / 2];
}
vi rev(n);
rep(i, 0, n) rev[i] = (rev[i / 2] | (i & 1) << L) / 2;
rep(i, 0, n) if (i < rev[i]) swap(a[i], a[rev[i]]);
for (int k = 1; k < n; k *= 2)
for (int i = 0; i < n; i += 2 * k)
rep(j, 0, k) {
// C z = rt[j+k] * a[i+j+k]; // (25% faster if hand-rolled) /// include-line
auto x = (double *) &rt[j + k], y = (double *) &a[i + j + k]; /// exclude-line
C z(x[0] * y[0] - x[1] * y[1], x[0] * y[1] + x[1] * y[0]); /// exclude-line
a[i + j + k] = a[i + j] - z;
a[i + j] += z;
}
}
template<int M>
vi convMod(const vi &a, const vi &b) {
if (a.empty() || b.empty()) return {};
vi res(sz(a) + sz(b) - 1);
int B = 32 - __builtin_clz(sz(res)), n = 1 << B, cut = int(sqrt(M));
vector<C> L(n), R(n), outs(n), outl(n);
rep(i, 0, sz(a)) L[i] = C((int) a[i] / cut, (int) a[i] % cut);
rep(i, 0, sz(b)) R[i] = C((int) b[i] / cut, (int) b[i] % cut);
fft(L), fft(R);
rep(i, 0, n) {
int j = -i & (n - 1);
outl[j] = (L[i] + conj(L[j])) * R[i] / (2.0 * n);
outs[j] = (L[i] - conj(L[j])) * R[i] / (2.0 * n) / 1i;
}
fft(outl), fft(outs);
rep(i, 0, sz(res)) {
ll av = ll(real(outl[i]) + .5), cv = ll(imag(outs[i]) + .5);
ll bv = ll(imag(outl[i]) + .5) + ll(real(outs[i]) + .5);
res[i] = ((av % M * cut + bv) % M * cut + cv) % M;
}
return res;
}
int mul(int a, int b) {
return 1ll * a * b % MOD;
}
int add(int a, int b) {
if (a < 0)a += MOD;
if (b < 0)b += MOD;
return (a + b) % MOD;
}
ll a, b;
int pw(int base, int p) {
if (p < 0)return 0;
if (!p) return 1LL;
int ret = pw(base, p >> 1LL);
ret = mul(ret, ret);
if (p & 1LL)
ret = mul(ret, base);
return ret;
}
int pw2(int base, int p) {
if (p < 0)return 0;
if (!p) return 1LL;
int ret = pw2(base, p >> 1LL);
ret = ret * ret % b;
if (p & 1LL)
ret = ret * base % b;
return ret;
}
typedef array<array<array<int, 10>, 10>, 255> mat;
mat base;
// dp[mod][first][last]
mat shift(const mat x, int sz) {
mat ret = mat();
ll s = pw2(10, sz);
for (int i = 0; i < b; ++i) {
for (int j = 0; j <= 9; ++j) {
for (int k = 0; k <= 9; ++k) {
ret[(s * i) % b][j][k] = add(ret[(s * i) % b][j][k], x[i][j][k]);
}
}
}
return ret;
}
mat merge(mat x, mat y) {
mat ret = mat();
for (int start = 0; start <= 9; ++start) {
for (int end = 0; end <= 9; ++end) {
vector<int> lf(b), rt(b);
for (int i = 0; i <= 9; ++i) {
for (int j = 0; j < b; ++j) {
lf[j] = add(lf[j], x[j][start][i]);
rt[j] = add(rt[j], y[j][i][end]);
}
}
vector<int> res = convMod<MOD>(lf, rt);
for (int i = 0; i < res.size(); ++i) {
ret[i % b][start][end] = add(ret[i % b][start][end], res[i]);
}
for (int i = 0; i <= 9; ++i) {
for (int j = 0; j < b; ++j) {
lf[j] = x[j][start][i];
rt[j] = y[j][i][end];
}
res = convMod<MOD>(lf, rt);
for (int j = 0; j < res.size(); ++j) {
ret[j % b][start][end] = add(ret[j % b][start][end], -res[j]);
}
}
}
}
return ret;
}
mat calc(ll n) {
if (n == 1) {
return base;
}
auto dp = calc(n / 2);
dp = merge(shift(dp, n / 2), dp);
if (n & 1)dp = merge(shift(dp, 1), base);
return dp;
}
void solve() {
cin >> a >> b;
int old = b;
b = 225;
base = mat();
for (int i = 0; i <= 9; ++i)base[i][i][i] = 1;
auto ret = calc(a);
ll ans = 0;
for (int i = 1; i <= 9; ++i) {
for (int j = 0; j <= 9; ++j) {
ans = add(ans, ret[old][i][j]);
}
}
cout << ans;
}
signed main() {
Gamal();
int t = 1;
// cin >> t;
while (t--) {
solve();
}
}
详细
Test #1:
score: 100
Accepted
time: 506ms
memory: 9496kb
input:
12345 200
output:
323756255
result:
ok single line: '323756255'
Test #2:
score: 0
Accepted
time: 221ms
memory: 6640kb
input:
100 87
output:
896364174
result:
ok single line: '896364174'
Test #3:
score: 0
Accepted
time: 229ms
memory: 6680kb
input:
100 35
output:
785970618
result:
ok single line: '785970618'
Test #4:
score: 0
Accepted
time: 459ms
memory: 9220kb
input:
5000 5
output:
176058968
result:
ok single line: '176058968'
Test #5:
score: 0
Accepted
time: 728ms
memory: 12012kb
input:
888888 88
output:
906317283
result:
ok single line: '906317283'
Test #6:
score: 0
Accepted
time: 1011ms
memory: 13460kb
input:
9999999 99
output:
133442170
result:
ok single line: '133442170'
Test #7:
score: -100
Wrong Answer
time: 1490ms
memory: 18596kb
input:
101010101010 127
output:
680153192
result:
wrong answer 1st lines differ - expected: '893501348', found: '680153192'