Chapter 130
HomeThe Number Theoretic Transform (NTT) is FFT over a finite field. It multiplies polynomials of degree N in O(N log N) with exact integer arithmetic (no floating point). Uses modulus 998244353 (2²³ × 7 × 17 + 1) where a primitive root of unity exists.
const long long MOD = 998244353, ROOT = 3;
long long mod_pow(long long a, long long e) { /* binary exp */ }
void ntt(vector& a, bool invert) {
int n = a.size();
for (int i = 1, j = 0; i < n; i++) {
int bit = n >> 1;
for (; j & bit; bit >>= 1) j ^= bit;
j ^= bit;
if (i < j) swap(a[i], a[j]);
}
for (int len = 2; len <= n; len <<= 1) {
long long wlen = mod_pow(ROOT, (MOD - 1) / len);
if (invert) wlen = mod_pow(wlen, MOD - 2);
for (int i = 0; i < n; i += len) {
long long w = 1;
for (int j = 0; j < len / 2; j++) {
long long u = a[i + j];
long long v = a[i + j + len / 2] * w % MOD;
a[i + j] = (u + v) % MOD;
a[i + j + len / 2] = (u - v + MOD) % MOD;
w = w * wlen % MOD;
}
}
}
if (invert) {
long long inv_n = mod_pow(n, MOD - 2);
for (auto& x : a) x = x * inv_n % MOD;
}
}
// Multiply: pad to power of 2, NTT both, pointwise multiply, inverse NTT.
// O(N log N).