Chapter 130

Home

NTT and Polynomial Multiplication

The 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.

NTT Implementation

C++ — NTT (iterative, Cooley-Tukey)

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).