求助 ntt 卡常
查看原帖
求助 ntt 卡常
563650
haochengw920楼主2024/5/1 10:34

rt, 50pts ,第六个点本地跑了两秒多

(这题真的不能扩大时限嘛

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define R register
#define int long long
#define Mod (998244353)
using namespace std;

char buf[200005], *p1 = buf, *p2 = buf;
#define getchar() ((p1==p2)&&(p2=(p1=buf)+fread(buf,1,200000,stdin),p1==p2)?EOF:*p1++)
inline int read() {
	R int x = 0; char c = getchar();
	while (!isdigit(c)) c = getchar();
	while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
	return x;
}
inline void write(R int x) {
	if (x > 9) write(x / 10);
	putchar(x % 10 + 48);
}

inline int fsp(R int x, R int p) {
	R int res = 1;
	for (; p; p >>= 1) {
		if (p & 1) res = res * x % Mod;
		x = x * x % Mod;
	}
	return res;
}

const int MAXN = 200005;
const int G = 3, InvG = 332748118;

int n, len, lm;
int a[MAXN], b[MAXN];
struct Poly {
	int len, inv, a[MAXN], rev[MAXN];
	inline int& operator [] (const R int &x) {
		return a[x];
	}
	inline void Init(R int ln, R int l) {
		len = ln, -- l, inv = fsp(len, Mod - 2);
		for (R int i = 1; i <= len; ++ i)
			rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << l);
	}
	inline Poly(R int len = 0, R int l = 0) {
		for (R int i = 0; i <= len; ++ i)
			a[i] = rev[i] = 0;
		Init(len, l);
	}
	inline void NTT(R int sgn) { 
		for (R int i = 0; i <= len; ++ i)
			if (i < rev[i]) swap(a[i], a[rev[i]]);
		for (R int flr = 2; flr <= len; flr <<= 1) {
			R int Wn = fsp(sgn == 1 ? G : InvG, (Mod - 1) / flr);
			for (R int mid = flr >> 1, l = 0; l < len; l += flr) {
				R int w = 1, x, y;
				for (R int i = l; i < l + mid; ++ i, w = w * Wn % Mod)
					x = a[i], y = w * a[i + mid] % Mod, 
					a[i] = (x + y) % Mod, a[i + mid] = (x - y + Mod) % Mod;
			}
		} 
		if (sgn == -1)
			for (R int i = 0; i <= len; ++ i)
				a[i] = (a[i] * inv) % Mod;
	}
}f, g;
inline Poly operator * (Poly &A, Poly &B) {
	R int len = 1, l = 0;
	while (len < A.len) len <<= 1, ++ l;
	Poly C(len, l);
	A.NTT(1), B.NTT(1);
	for (R int i = 0; i <= len; ++ i)
		C[i] = (A[i] * B[i]) % Mod;
	/*A.NTT(-1), B.NTT(-1), */C.NTT(-1);
	return C;
}

inline void CDQ(R int l, R int r) {
	if (l == r) {
		if (!l) a[l] = 1;
		return;
	}
	R int mid = (l + r) >> 1;
	CDQ(l, mid); len = 1, lm = 0;
	while (len <= (r - l + 1)) len <<= 1, ++ lm;
	f.Init(len, lm), g.Init(len, lm); 
	memcpy(f.a, a + l, sizeof(int) * (mid - l + 1));
	memcpy(g.a, b, sizeof(int) * (r - l + 1));
	memset(f.a + mid - l + 1, 0, sizeof(int) * (len - mid + l));
	memset(g.a + r - l + 1, 0, sizeof(int) * (len - r + l));
	f = f * g;
	for (R int i = mid + 1; i <= r; ++ i)
		a[i] = (a[i] + f.a[i - l]) % Mod;
	CDQ(mid + 1, r);
}

signed main()
{
	n = read();
	for (R int i = 1; i < n; ++ i) b[i] = read();
	CDQ(0, n - 1);
	for (R int i = 0; i < n; ++ i) write(a[i]), putchar(' ');
	return puts(""), 0;
}
2024/5/1 10:34
加载中...