QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#561119 | #8329. Excuse | zhouyuhang | AC ✓ | 372ms | 19456kb | C++14 | 4.2kb | 2024-09-12 20:20:41 | 2024-09-12 20:20:42 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10, P = 998244353;
namespace ModInt {
inline int add(int x, int y) { return x + y >= P ? x + y - P : x + y;}
inline int sub(int x, int y) { return x < y ? x - y + P : x - y;}
inline int mul(int x, int y) { return 1ll * x * y % P;}
inline int Pow(int x, int y) { int r = 1; for (; y; y >>= 1, x = mul(x, x)) if (y & 1) r = mul(r, x); return r;}
inline int inv(int x) { return Pow(x, P - 2);}
}
using namespace ModInt;
int n;
int fac[N], ifac[N];
void init(int n) {
fac[0] = 1;
for (int i = 1; i <= n; ++i) fac[i] = mul(fac[i - 1], i);
ifac[n] = inv(fac[n]);
for (int i = n; i; --i) ifac[i - 1] = mul(ifac[i], i);
}
namespace POLY {
using Poly = vector<int>;
int r[1 << 20], len;
void Init(int n) {
len = 1; while (len < n) len <<= 1;
for (int i = 1; i < len; ++i) {
r[i] = r[i >> 1] >> 1;
if (i & 1) r[i] |= (len >> 1);
}
}
Poly G[20];
void Prework() {
for (int i = 0; i < 20; ++i) {
Poly &Gi = G[i]; Gi = Poly(1 << i, 1);
const int t = Pow(3, P >> i + 1);
for (int j = 1; j < (1 << i); ++j) Gi[j] = mul(Gi[j - 1], t);
}
}
void Dft(Poly &a, int type = 1, int n = len) {
a.resize(n);
for (int i = 0; i < n; ++i) if (i < r[i]) swap(a[i], a[r[i]]);
for (int i = 1, o = 0; i < n; i <<= 1, ++o) {
const Poly Go = G[o];
for (int j = 0; j < n; j += (i << 1)) {
for (int k = 0; k < i; ++k) {
int tx = a[j + k], ty = mul(Go[k], a[i + j + k]);
a[j + k] = add(tx, ty), a[i + j + k] = sub(tx, ty);
}
}
}
if (type == -1) {
reverse(a.begin() + 1, a.end());
const int t = inv(n);
for (int i = 0; i < n; ++i) a[i] = mul(a[i], t);
}
}
Poly operator +(Poly x, Poly y) {
int tx = x.size(), ty = y.size(); Poly z(max(tx, ty));
for (int i = 0; i < tx; ++i) z[i] = add(z[i], x[i]);
for (int i = 0; i < ty; ++i) z[i] = add(z[i], y[i]);
return z;
}
Poly operator -(Poly x, Poly y) {
int tx = x.size(), ty = y.size(); Poly z(max(tx, ty));
for (int i = 0; i < tx; ++i) z[i] = add(z[i], x[i]);
for (int i = 0; i < ty; ++i) z[i] = sub(z[i], y[i]);
return z;
}
Poly operator *(Poly x, Poly y) {
int tx = x.size(), ty = y.size();
if (tx <= 50 && ty <= 50) {
Poly z(tx + ty - 1);
for (int i = 0; i < tx; ++i) {
for (int j = 0; j < ty; ++j) {
z[i + j] = (z[i + j] + 1ll * x[i] * y[j]) % P;
}
}
return z;
}
Init(tx + ty), Dft(x), Dft(y);
for (int i = 0; i < len; ++i) x[i] = mul(x[i], y[i]);
Dft(x, -1), x.resize(tx + ty - 1); return x;
}
Poly Inv(Poly x) {
int n = x.size();
if (n == 1) return {inv(x[0])};
Poly y = Inv(Poly(x.begin(), x.begin() + (n + 1) / 2));
Init(n << 1), Dft(x), Dft(y);
for (int i = 0; i < len; ++i) x[i] = mul(y[i], sub(2, mul(x[i], y[i])));
Dft(x, -1), x.resize(n);
return x;
}
Poly Der(Poly x) {
Poly ret(x.size() - 1);
for (int i = 0; i + 1 < x.size(); ++i) ret[i] = mul(i + 1, x[i + 1]);
return ret;
}
Poly Int(Poly x) {
Poly ret(x.size() + 1);
for (int i = 1; i <= x.size(); ++i) ret[i] = mul(mul(ifac[i], fac[i - 1]), x[i - 1]);
return ret;
}
Poly Ln(Poly x) {
int n = x.size();
Poly ret = Der(x) * Inv(x); ret.resize(n - 1);
return Int(ret);
}
Poly Exp(Poly x) {
int n = x.size();
if (n == 1) return Poly{1};
Poly y = Exp(Poly(x.begin(), x.begin() + (n + 1) / 2)); y.resize(n);
x = (x - Ln(y) + Poly{1}) * y, x.resize(n);
return x;
}
};
using namespace POLY;
int a[N];
int main() {
Prework();
cin >> n;
init(n);
Poly f(n);
for (int i = 0; i < n; ++i) f[i] = ifac[i + 1];
f = Ln(f);
for (int i = 1, t = 2; i < n; ++i, t = add(t, t)) f[i] = mul(f[i], inv(t - 1));
Poly g = Exp(f);
f = f * Poly{-1} + Poly{0, 1};
Poly h = Exp(f);
for (int i = 0, x = 1, y = 1; i < n; ++i, x = mul(x, y), y = add(y, y)) h[i] = mul(h[i], x);
for (int i = 1; i <= n; ++i) a[i] = mul(P + 1 >> 1, add(h[i - 1], a[i - 1]));
for (int i = 0, x = 1, y = 1; i <= n; ++i, x = mul(x, y), y = mul(y, P + 1 >> 1)) {
a[i] = mul(a[i], x);
}
int ans = 0;
for (int i = 1; i <= n; ++i) ans = add(ans, mul(a[i], g[n - i]));
ans = mul(ans, fac[n]);
cout << ans << endl;
return 0;
}
这程序好像有点Bug,我给组数据试试?
詳細信息
Test #1:
score: 100
Accepted
time: 3ms
memory: 9136kb
input:
1
output:
499122177
result:
ok 1 number(s): "499122177"
Test #2:
score: 0
Accepted
time: 3ms
memory: 9292kb
input:
3
output:
561512450
result:
ok 1 number(s): "561512450"
Test #3:
score: 0
Accepted
time: 7ms
memory: 9128kb
input:
10
output:
609769250
result:
ok 1 number(s): "609769250"
Test #4:
score: 0
Accepted
time: 0ms
memory: 11580kb
input:
1000
output:
475714976
result:
ok 1 number(s): "475714976"
Test #5:
score: 0
Accepted
time: 9ms
memory: 11544kb
input:
1024
output:
178624793
result:
ok 1 number(s): "178624793"
Test #6:
score: 0
Accepted
time: 372ms
memory: 18432kb
input:
100000
output:
537516197
result:
ok 1 number(s): "537516197"
Test #7:
score: 0
Accepted
time: 368ms
memory: 18912kb
input:
99471
output:
489775976
result:
ok 1 number(s): "489775976"
Test #8:
score: 0
Accepted
time: 187ms
memory: 14556kb
input:
65536
output:
171446457
result:
ok 1 number(s): "171446457"
Test #9:
score: 0
Accepted
time: 370ms
memory: 19456kb
input:
84792
output:
371578800
result:
ok 1 number(s): "371578800"
Test #10:
score: 0
Accepted
time: 372ms
memory: 17660kb
input:
93846
output:
841905002
result:
ok 1 number(s): "841905002"
Extra Test:
score: 0
Extra Test Passed