hdu6061[NTT推公式] 2017多校3

/*hdu6061[NTT推公式] 2017多校3*/
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MOD = 998244353;
const int MAX_N = 1000000;
int n, m, temp;
LL a;
LL inv[1000007];
LL Finv[1000007];
LL F[1000007];
LL A[500005], B[500005], C[500005];
LL quickPow(LL x, LL n, LL MOD) {
    LL ans = 1;
    for (; n; n >>= 1) {
        if (n & 1) ans = (ans * x) % MOD;
        x = (x * x) % MOD;
    }
    return ans;
}

void inv_init() {
    inv[1] = 1;
    for (int i = 2; i <= MAX_N; ++i) {
        inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;
    }
    F[0] = Finv[0] = 1;
    for (int i = 1; i <= MAX_N; ++i) {
        F[i] = F[i - 1] * 1LL * i % MOD;
        Finv[i] = Finv[i - 1] * 1LL * inv[i] % MOD;
    }
}
/*
ntt.run(a, len, 1, MOD);
ntt.run(b, len, 1, MOD);
REP(0, len) c[i] = a[i] * b[i] % MOD;
ntt.run(c, len, -1, MOD);
*/
struct NTT {
    enum {g = 3};
    // @private
    int rev(int x, int r) {
        int ans = 0;
        for (int i = 0; i < r; i++) {
            if (x & (1 << i)) ans += 1 << (r - i - 1);
        }
        return ans;
    }
    // @public
    void run(LL a[], int n, int on, LL MOD) {
        int r = (int)log2(n + 1e-4);
        for (int i = 0; i < n; i++) {
            int tmp = rev(i, r);
            if (i < tmp) swap(a[i], a[tmp]);
        }
        for (int s = 1; s <= r; s++) {
            int m = 1 << s;
            LL wn = quickPow(g, (MOD - 1) / m, MOD);
            for (int k = 0; k < n; k += m) {
                LL w = 1;
                for (int j = 0; j < (m >> 1); j++) {
                    LL t = w * (a[k + j + (m >> 1)] % MOD) % MOD, u = a[k + j] % MOD;
                    a[k + j] = (u + t) % MOD;
                    a[k + j + (m >> 1)] = ((u - t) % MOD + MOD) % MOD;
                    w *= wn; w %= MOD;
                }
            }
        }
        if (on < 0) {
            for (int i = 1; i < (n >> 1); i++) swap(a[i], a[n - i]);
            LL inv = quickPow(n, MOD - 2, MOD);
            for (int i = 0; i < n; i++) a[i] = a[i] % MOD * inv % MOD;
        }
    }
} ntt;
int main() {
    inv_init();
    while (~scanf("%d", &n)) {
        a = 0;
        for (int i = 0; i <= n; i++) {
            scanf("%lld", &C[i]);
        }
        scanf("%d", &m);
        for (int i = 0; i < m; i++) {
            scanf("%d", &temp);
            a -= temp;
            if (a <= 0) a += MOD;
        }
        LL temp = 1LL;
        int len = 1; while (len < (2 * n)) len <<= 1;
        for (int i = 0; i < len; i++) {
            if (i <= n) {
                A[i] = temp * Finv[i] % MOD;
                B[i] = F[n - i] * C[n - i] % MOD;
            }
            else A[i] = B[i] = 0;
            temp = (temp * a) % MOD;
        }
        ntt.run(A, len, 1, MOD);
        ntt.run(B, len, 1, MOD);
        for (int i = 0; i < len; i++) {
            A[i] = (A[i] * B[i]) % MOD;
        }
        ntt.run(A, len, -1, MOD);
        for (int i = 0; i <= n; i++) {
            //cout << A[i] << endl;
            A[i] = (A[i] % MOD + MOD) % MOD * Finv[n - i] % MOD;
        }
        for (int i = 0; i <= n; i++) {
            printf("%lld ", A[n - i]);
        }
        puts("");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/UnderSilenceee/p/7276830.html