嗯是这样的我是一个不会卡常的弱智,板子也没怎么修过,然后这就被卡住了
想请教一下怎么让我的代码变快点呢?谢谢!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ri register int
const int MAXN = 2000005, MOD = 998244353, Gen = 3;
ll q_pow(ll a, ll b, ll p = MOD) {
ll ret = 1;
for (; b; a = a * a % p, b >>= 1) if (b & 1) ret = ret * a % p;
return ret;
}
ll inv(ll x, ll p = MOD) { return q_pow(x, p - 2, p); }
int rev[MAXN], fac[MAXN], ifac[MAXN], I[MAXN], Wn[MAXN], iWn[MAXN];
void NTT(int* A, int LIM, int op) {
for (ri i = 0; i < LIM; ++i) if (i < rev[i]) swap(A[i], A[rev[i]]);
for (ri l = 2, t = 1; l <= LIM; l <<= 1, ++t) {
int g = op == -1 ? iWn[t] : Wn[t];
for (ri i = 0; i < LIM; i += l) {
int w = 1;
for (ri j = i; j < i + (l >> 1); ++j, w = 1ll * w * g % MOD) {
int x = A[j], y = 1ll * w * A[j + (l >> 1)] % MOD;
A[j] = (x + y) % MOD, A[j + (l >> 1)] = (x - y) % MOD;
}
}
}
if (op == -1) {
int invLIM = inv(LIM);
for (ri i = 0; i < LIM; ++i) A[i] = 1ll * A[i] * invLIM % MOD;
}
}
void Multiply(int* A, int* B, int LIM, int L) {
for (ri i = 0; i < LIM; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (L - 1));
NTT(A, LIM, 1), NTT(B, LIM, 1);
for (ri i = 0; i < LIM; ++i) A[i] = 1ll * A[i] * B[i] % MOD;
NTT(A, LIM, -1);
}
int Tinv[MAXN];
void Inverse(const int* F, int* G, int LIM, int L) {
if (LIM == 1) { G[0] = inv(F[0]); return; }
Inverse(F, G, LIM >> 1, L - 1);
for (ri i = 0; i < LIM; ++i) Tinv[i] = F[i];
for (ri i = LIM; i < (LIM << 1); ++i) Tinv[i] = 0;
for (ri i = 0; i < (LIM << 1); ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << L);
NTT(Tinv, LIM << 1, 1), NTT(G, LIM << 1, 1);
for (ri i = 0; i < (LIM << 1); ++i) G[i] = (2 * G[i] - 1ll * Tinv[i] * G[i] % MOD * G[i]) % MOD;
NTT(G, LIM << 1, -1);
for (ri i = LIM; i < (LIM << 1); ++i) G[i] = 0;
}
void Derivative(const int* F, int* G, int LIM) {
for (ri i = 0; i < LIM - 1; ++i) G[i] = 1ll * F[i + 1] * (i + 1) % MOD;
G[LIM - 1] = 0;
}
void Inter(const int* F, int* G, int LIM) {
for (ri i = 1; i < LIM; ++i) G[i] = 1ll * F[i - 1] * I[i] % MOD;
G[0] = 0;
}
int Tln[MAXN];
void Ln(const int* F, int* G, int LIM, int L) {
Inverse(F, Tln, LIM, L);
Derivative(F, G, LIM);
Multiply(Tln, G, LIM << 1, L + 1);
Inter(Tln, G, LIM);
for (ri i = 0; i < (LIM << 1); ++i) Tln[i] = 0;
for (ri i = LIM; i < (LIM << 1); ++i) G[i] = 0;
}
int Texp[MAXN], Texp2[MAXN];
void Exp(const int* F, int* G, int LIM, int L) {
if (LIM == 1) { G[0] = 1; return; }
Exp(F, G, LIM >> 1, L - 1);
for (ri i = 0; i < LIM; ++i) Texp[i] = G[i];
Ln(G, Texp2, LIM, L);
for (ri i = 0; i < LIM; ++i) G[i] = (-Texp2[i] + F[i]) % MOD;
++G[0];
Multiply(G, Texp, LIM << 1, L + 1);
for (ri i = LIM; i < (LIM << 1); ++i) G[i] = 0;
for (ri i = 0; i < (LIM << 1); ++i) Texp[i] = 0;
for (ri i = 0; i < (LIM << 1); ++i) Texp2[i] = 0;
}
int K, N, LIM = 1, L, F[MAXN], G[MAXN], H[MAXN];
int main() {
scanf("%d%d", &K, &N);
Wn[0] = iWn[0] = 1;
while (LIM <= N + 1) LIM <<= 1, ++L, Wn[L] = q_pow(Gen, (MOD - 1) / LIM), iWn[L] = inv(Wn[L]);
Wn[L + 1] = q_pow(Gen, (MOD - 1) / (LIM << 1)), iWn[L + 1] = inv(Wn[L + 1]);
fac[0] = ifac[0] = fac[1] = ifac[1] = I[1] = 1;
for (ri i = 2; i <= LIM; ++i) {
fac[i] = 1ll * fac[i - 1] * i % MOD, I[i] = -1ll * (MOD / i) * I[MOD % i] % MOD, ifac[i] = 1ll * ifac[i - 1] * I[i] % MOD;
}
F[1] = K + 1;
Exp(F, G, LIM, L);
for (ri i = 0; i < LIM; ++i) G[i] = (G[i + 1] - ifac[i + 1]) % MOD;
for (ri i = 0; i < LIM; ++i) F[i] = ifac[i + 1];
Inverse(F, H, LIM, L);
Multiply(G, H, LIM << 1, L + 1);
for (ri i = LIM; i < (LIM << 1); ++i) G[i] = 0;
G[0] = 0;
for (ri i = 1; i < LIM; ++i) G[i] = 1ll * (i & 1 ? 1 : -1) * G[i] * fac[i] % MOD * I[i] % MOD;
for (ri i = 0; i < LIM; ++i) F[i] = 0;
Exp(G, F, LIM, L);
for (ri i = 1; i <= N; ++i) printf("%d\n", (1ll * fac[i] * F[i] % MOD + MOD) % MOD);
return 0;
}