QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#19506 | #1423. Bin | qingaodong | AC ✓ | 4595ms | 45524kb | C++20 | 5.5kb | 2022-02-02 11:03:18 | 2022-05-06 05:36:33 |
Judging History
answer
#pragma GCC optimize("O3")
#include <iostream>
#include <complex>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>
#include <numeric>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <cmath>
#include <bitset>
#include <cassert>
#include <queue>
#include <stack>
#include <deque>
#include <random>
#include <climits>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef long double ld;
#define TIME (clock() * 1.0 / CLOCKS_PER_SEC)
const int M = 1e6 + 239;
const int MOD = 998244353;
const ll MOD2 = (ll)MOD * (ll)MOD;
int mul(long long a, int b) {
return a * b % MOD;
}
int power(int a, int b) {
int ans = 1;
while (b) {
if (b & 1) ans = mul(ans, a);
a = mul(a, a);
b >>= 1;
}
return ans;
}
const int wp = power(3, 7 * 17); // w^(2^23) == 1
namespace fft {
int k;
vector<int> rev;
vector<int> st;
void fft(vector<int> &a) {
for (int i = 0; i < k; i++)
if (rev[i] < i)
swap(a[rev[i]], a[i]);
int w, wn, ai, aj;
for (int s = 1, it = 0; s < k; s <<= 1, it++) {
wn = st[it];
for (int l = 0; l < k; l += s + s) {
w = 1;
for (int i = l, j = l + s; i < l + s; i++, j++) {
ai = a[i];
aj = 1LL * w * a[j] % MOD; // or st[((1 << 22) / s) * (i - l)]
a[i] = ai + aj;
if (a[i] >= MOD)
a[i] -= MOD;
a[j] = ai - aj;
if (a[j] < 0)
a[j] += MOD;
w = 1LL * w * wn % MOD;
}
}
}
}
vector<int> mult(vector<int> a, vector<int> b) {
k = 1;
while (k < (int)a.size() + (int)b.size() - 1)
k <<= 1;
st.clear();
st.push_back(power(wp, ((1 << 22) / k)));
for (int t = 1; t < k; t <<= 1)
st.push_back(1LL * st.back() * st.back() % MOD);
reverse(st.begin(), st.end());
rev.clear();
rev.resize(k);
rev[0] = 0;
for (int i = 1; i < k; i++) {
if (i & 1)
rev[i] = rev[i - 1] + (k >> 1);
else
rev[i] = rev[i >> 1] >> 1;
}
a.resize(k);
fft(a);
b.resize(k);
fft(b);
vector<int> pr(k);
for (int i = 0; i < k; i++)
pr[i] = 1LL * a[i] * b[i] % MOD;
fft(pr);
reverse(pr.begin() + 1, pr.end());
int inv_k = power(k, MOD - 2);
for (int i = 0; i < k; i++)
pr[i] = 1LL * pr[i] * inv_k % MOD;
while (pr.back() == 0)
pr.pop_back(); // can be removed
return pr;
}
}
int n, k;
const int MG = 15000;
const int MM = 1.1e6;
int c[MM * 2];
int dp[MM];
vector<int> values[30];
vector<pair<int, int>> cur;
int main() {
#ifdef ONPC
freopen("input", "r", stdin);
#endif
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> k;
dp[0] = 0;
cur = {{0, 1}};
for (int i = 1; i <= n; i++)
{
ll sum = 0;
for (int x = max(0, (i / 2) - k); x <= min(i - 1, (i / 2) + k); x++)
if (abs(x - (i - x)) <= k)
{
sum += (ll)dp[x] * dp[i - x];
if (sum >= MOD2)
sum -= MOD2;
}
dp[i] = ((c[i] % MOD) + (sum % MOD));
if (dp[i] >= MOD)
dp[i] -= MOD;
if (dp[i] & 1)
dp[i] += MOD;
dp[i] /= 2;
if (i == 1) dp[i] = 1;
// cout << "!!!!" << dp[i] << ' ' << c[i] << ' ' << sum << '\n';
cur.push_back({i, 1});
while (cur.size() >= 2 && cur.back().second == cur[cur.size() - 2].second) {
int id = cur.size() - 2;
for (int j = 0; j < values[id].size(); ++j) {
c[j + cur[id].first] -= values[id][j];
if (c[j + cur[id].first] < 0) {
c[j + cur[id].first] += MOD;
}
}
values[id].clear();
cur[id].second <<= 1;
cur.pop_back();
}
vector<int> a, b;
// for (auto [a, b] : cur) {
// cout << a << ' ' << b << '\n';
// }
for (int j = 0; j < cur.back().second * 2 && j <= i; ++j) {
a.push_back(dp[j]);
}
for (int j = 0; j < cur.back().second; ++j) {
b.push_back(dp[cur.back().first + j]);
}
values[cur.size() - 1] = fft::mult(a, b);
int id = cur.size() - 1;
if (cur.size() != 1) {
for (auto &i : values[id]) {
i += i;
if (i >= MOD) {
i -= MOD;
}
}
}
for (int j = 0; j < values[id].size(); ++j) {
c[j + cur[id].first] += values[id][j];
if (c[j + cur[id].first] >= MOD) {
c[j + cur[id].first] -= MOD;
}
}
// for (auto j : values[id])cout << j << ' ';cout << '\n';
// for (auto j : a)cout << j << '.';cout << '\n';
// for (auto j : b)cout << j << '.';cout << '\n';
}
cout << dp[n] << "\n";
cerr << TIME << "\n";
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 5808kb
input:
2 0
output:
1
result:
ok 1 number(s): "1"
Test #2:
score: 0
Accepted
time: 0ms
memory: 5900kb
input:
3 0
output:
1
result:
ok 1 number(s): "1"
Test #3:
score: 0
Accepted
time: 0ms
memory: 5900kb
input:
3 1
output:
2
result:
ok 1 number(s): "2"
Test #4:
score: 0
Accepted
time: 0ms
memory: 5896kb
input:
4 0
output:
2
result:
ok 1 number(s): "2"
Test #5:
score: 0
Accepted
time: 3ms
memory: 5856kb
input:
4 1
output:
3
result:
ok 1 number(s): "3"
Test #6:
score: 0
Accepted
time: 0ms
memory: 5764kb
input:
4 2
output:
5
result:
ok 1 number(s): "5"
Test #7:
score: 0
Accepted
time: 3ms
memory: 5900kb
input:
6 2
output:
23
result:
ok 1 number(s): "23"
Test #8:
score: 0
Accepted
time: 0ms
memory: 5956kb
input:
7 42
output:
132
result:
ok 1 number(s): "132"
Test #9:
score: 0
Accepted
time: 3ms
memory: 5900kb
input:
10 1
output:
400
result:
ok 1 number(s): "400"
Test #10:
score: 0
Accepted
time: 3ms
memory: 5852kb
input:
13 4
output:
42003
result:
ok 1 number(s): "42003"
Test #11:
score: 0
Accepted
time: 4ms
memory: 5844kb
input:
239 17
output:
385818773
result:
ok 1 number(s): "385818773"
Test #12:
score: 0
Accepted
time: 171ms
memory: 9468kb
input:
50216 58
output:
744498776
result:
ok 1 number(s): "744498776"
Test #13:
score: 0
Accepted
time: 3654ms
memory: 45440kb
input:
787788 78
output:
394429402
result:
ok 1 number(s): "394429402"
Test #14:
score: 0
Accepted
time: 3ms
memory: 5908kb
input:
5 92
output:
14
result:
ok 1 number(s): "14"
Test #15:
score: 0
Accepted
time: 3ms
memory: 5856kb
input:
88 79
output:
931161641
result:
ok 1 number(s): "931161641"
Test #16:
score: 0
Accepted
time: 1ms
memory: 5804kb
input:
749 77
output:
615055472
result:
ok 1 number(s): "615055472"
Test #17:
score: 0
Accepted
time: 4ms
memory: 6040kb
input:
2281 89
output:
282226588
result:
ok 1 number(s): "282226588"
Test #18:
score: 0
Accepted
time: 8ms
memory: 5912kb
input:
5765 35
output:
293680396
result:
ok 1 number(s): "293680396"
Test #19:
score: 0
Accepted
time: 132ms
memory: 9604kb
input:
43189 12
output:
805295564
result:
ok 1 number(s): "805295564"
Test #20:
score: 0
Accepted
time: 3539ms
memory: 45256kb
input:
806855 5
output:
593114139
result:
ok 1 number(s): "593114139"
Test #21:
score: 0
Accepted
time: 4414ms
memory: 45464kb
input:
994514 45
output:
678426421
result:
ok 1 number(s): "678426421"
Test #22:
score: 0
Accepted
time: 4486ms
memory: 45464kb
input:
999921 62
output:
752162081
result:
ok 1 number(s): "752162081"
Test #23:
score: 0
Accepted
time: 4574ms
memory: 45424kb
input:
995033 94
output:
130314865
result:
ok 1 number(s): "130314865"
Test #24:
score: 0
Accepted
time: 4138ms
memory: 45524kb
input:
901438 97
output:
809128292
result:
ok 1 number(s): "809128292"
Test #25:
score: 0
Accepted
time: 4308ms
memory: 45428kb
input:
993020 0
output:
926771801
result:
ok 1 number(s): "926771801"
Test #26:
score: 0
Accepted
time: 4595ms
memory: 45428kb
input:
1000000 100
output:
470305140
result:
ok 1 number(s): "470305140"