QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#262798 | #4491. Find the Number of Paths | ucup-team1198 | AC ✓ | 4749ms | 43220kb | C++14 | 5.1kb | 2023-11-24 03:19:06 | 2023-11-24 03:19:06 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
const int MOD = 998244353;
int add(int a, int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int sub(int a, int b) {
return a >= b ? a - b : a + MOD - b;
}
int mul(int a, int b) {
return (1ll * a * b) % MOD;
}
int pw(int x, int n) {
int res = 1;
while (n) {
if (n % 2 == 0) {
x = mul(x, x);
n /= 2;
} else {
res = mul(res, x);
n--;
}
}
return res;
}
const int G = 3;
void fft(vector<int>& a, bool inv = false) {
int n = a.size();
int k = 0;
while ((1 << k) < n) ++k;
static vector<int> rev, power = {0, 1};
rev.resize(n);
rev[0] = 0;
for (int i = 1; i < n; ++i) {
rev[i] = rev[i / 2] / 2 + ((i & 1) << (k - 1));
if (i < rev[i]) {
swap(a[i], a[rev[i]]);
}
}
for (int l = 1; l < n; l *= 2) {
if ((int)power.size() == l) {
power.resize(2 * l);
int w = pw(G, (MOD - 1) / 2 / l);
for (int i = l; i < 2 * l; ++i) {
power[i] = power[i / 2];
if (i & 1) {
power[i] = mul(power[i], w);
}
}
}
for (int i = 0; i < n; i += 2 * l) {
for (int j = 0; j < l; ++j) {
int x = a[i + j], y = mul(a[i + j + l], power[j + l]);
a[i + j] = add(x, y);
a[i + j + l] = sub(x, y);
}
}
}
if (inv) {
int anti = pw(n, MOD - 2);
reverse(a.begin() + 1, a.end());
for (int i = 0; i < n; ++i) {
a[i] = mul(a[i], anti);
}
}
}
vector<int> operator*(vector<int> a, vector<int> b) {
int sz = a.size() + b.size() - 1;
int k = 0;
while ((1 << k) < sz) ++k;
a.resize(1 << k);
b.resize(1 << k);
fft(a);
fft(b);
for (int i = 0; i < (1 << k); ++i) {
a[i] = mul(a[i], b[i]);
}
fft(a, true);
a.resize(sz);
return a;
}
vector<int> operator+(const vector<int>& a, const vector<int>& b) {
vector<int> c(max(a.size(), b.size()));
for (int i = 0; i < (int)a.size(); ++i) {
c[i] = a[i];
}
for (int i = 0; i < (int)b.size(); ++i) {
c[i] = add(c[i], b[i]);
}
return c;
}
vector<int> operator-(const vector<int>& a, const vector<int>& b) {
vector<int> c(max(a.size(), b.size()));
for (int i = 0; i < (int)a.size(); ++i) {
c[i] = a[i];
}
for (int i = 0; i < (int)b.size(); ++i) {
c[i] = sub(c[i], b[i]);
}
return c;
}
vector<int> inv(vector<int> a, int n) {
vector<int> b = {pw(a[0], MOD - 2)};
static vector<int> a1;
int m = 1;
while (m < n) {
a1.resize(2 * m);
fill(a1.begin(), a1.end(), 0);
for (int i = 0; i < (int)a.size() && i < 2 * m; ++i) {
a1[i] = a[i];
}
b = b + b - a1 * b * b;
b.resize(2 * m);
m *= 2;
}
b.resize(n);
return b;
}
const int MAXF = 2e6;
int fact[MAXF], invf[MAXF];
vector<int> der(vector<int> a) {
if ((int)a.size() == 1) {
return {0};
}
for (int i = 1; i < (int)a.size(); ++i) {
a[i - 1] = mul(i, a[i]);
}
a.pop_back();
return a;
}
vector<int> integ(vector<int> a) {
a.push_back(0);
for (int i = (int)a.size() - 2; i >= 0; --i) {
a[i + 1] = mul(a[i], mul(invf[i + 1], fact[i]));
}
a[0] = 0;
return a;
}
vector<int> ln(vector<int> a, int n) {
auto res = integ(der(a) * inv(a, n));
res.resize(n);
return res;
}
vector<int> exp(vector<int> f, int n) {
vector<int> g = {1};
int m = 1;
static vector<int> f1;
while (m < n) {
f1.resize(2 * m);
fill(f1.begin(), f1.end(), 0);
for (int i = 0; i < (int)f.size() && i < 2 * m; ++i) {
f1[i] = f[i];
}
g = (f1 - ln(g, 2 * m) + vector<int>(1, 1)) * g;
g.resize(2 * m);
m *= 2;
}
g.resize(n);
return g;
}
void solve() {
int n, k;
cin >> n >> k;
vector<int> a(n);
for (int i = 1; i < n; ++i) {
cin >> a[i];
}
vector<int> eia = exp(integ(a), max(n, k + 1));
vector<int> cur(n + k);
for (int i = 0; i <= k; ++i) {
cur[i + n - 1] = eia[i];
}
vector<int> der_cur(n);
for (int i = 0; i < n; ++i) {
der_cur[i] = mul(cur[i + k], mul(fact[i + k], invf[i]));
}
vector<int> ans = der_cur * inv(eia, n);
for (int i = n - 1; i >= 0; --i) {
cout << ans[i] << " ";
}
cout << "\n";
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
fact[0] = 1;
for (int i = 1; i < MAXF; ++i) {
fact[i] = mul(fact[i - 1], i);
}
invf[MAXF - 1] = pw(fact[MAXF - 1], MOD - 2);
for (int i = MAXF - 1; i > 0; --i) {
invf[i - 1] = mul(invf[i], i);
}
int tst;
cin >> tst;
while (tst--) {
solve();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 4749ms
memory: 43220kb
input:
14 3 2 1 2 3 1 1 2 7 10 1 1 4 5 1 4 2 1 998244352 18 32 1 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 1 188 19 633886818 153877981 415015507 40745200 269787796 274990221 297547338 934403707 463583160 490465672 641355195 897012511 641637182 821068661 614724038 55504516 717220803 796828809 578138752 516258420 ...
output:
5 0 2 0 2 0 475251424 113315999 791330691 478266847 175921200 46569600 4082400 0 1 290297689 111948457 905336170 325091865 481715174 560516169 711953201 909617930 834449213 230629315 299970170 870572449 496138561 512305244 580683156 556935218 282162750 458443581 900977301 704879246 103685386 11...
result:
ok 14 lines