萌新求助
  • 板块P5850 calc加强版
  • 楼主Mr_Wu
  • 当前回复6
  • 已保存回复6
  • 发布时间2020/5/6 21:36
  • 上次更新2023/11/7 02:59:54
查看原帖
萌新求助
62308
Mr_Wu楼主2020/5/6 21:36

嗯是这样的我是一个不会卡常的弱智,板子也没怎么修过,然后这就被卡住了

想请教一下怎么让我的代码变快点呢?谢谢!

#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;
}
2020/5/6 21:36
加载中...