NTT模版

NTT模版

cpp
struct NTT {
    const int MOD = 998244353;
    const int G = 3;
    int qpow(int a, int b) {
        int res = 1;
        while (b > 0) {
            if (b & 1) res = res * a % MOD;
            a = a * a % MOD;
            b >>= 1;
        }
        return res;
    }
    vector<int> rev, rt;
    void init(int n) {
        if (sz(rev) == n) return;
        rev.resize(n);
        for (int i = 0; i < n; i++) {
            rev[i] = (rev[i >> 1] >> 1) | ((i & 1) * (n >> 1));
        }
        if (rt.empty()) {
            rt = {1, 1};
        }
        for (int k = rt.size(); k < n; k *= 2) {
            rt.resize(k * 2);
            int z = qpow(G, (MOD - 1) / (k * 2));
            for (int i = k / 2; i < k; i++) {
                rt[2 * i] = rt[i];
                rt[2 * i + 1] = rt[i] * z % MOD;
            }
        }
    }
    void transform(vector<int>& a, bool inv) {
        int n = sz(a);
        init(n);
        for (int i = 0; i < n; i++) {
            if (i < rev[i]) swap(a[i], a[rev[i]]);
        }
        for (int k = 1; k < n; k *= 2) {
            for (int i = 0; i < n; i += 2 * k) {
                for (int j = 0; j < k; j++) {
                    int u = a[i + j];
                    int v = a[i + j + k] * rt[k + j] % MOD;
                    a[i + j] = u + v >= MOD ? u + v - MOD : u + v;
                    a[i + j + k] = u - v < 0 ? u - v + MOD : u - v;
                }
            }
        }
        if (inv) {
            reverse(a.begin() + 1, a.end());
            int inv_n = qpow(n, MOD - 2);
            for (int& x : a) x = x * inv_n % MOD;
        }
    }
    vector<int> multiply(const vector<int>& A, const vector<int>& B) {
        if (A.empty() || B.empty()) return {};
        int tot = sz(A) + sz(B) - 1;
        int sz = 1;
        while (sz < tot) sz <<= 1;
        vector<int> a = A, b = B;
        a.resize(sz);
        b.resize(sz);
        transform(a, false);
        transform(b, false);
        for (int i = 0; i < sz; i++) {
            a[i] = a[i] * b[i] % MOD;
        }
        transform(a, true);
        a.resize(tot);
        return a;
    }
};
多项式全家桶模版
CF题解——Sliding Tree