NTT板子 -- from ACdreamer -- test by HDU6061
NTT板子
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; const int MAXN = 400040; typedef long long LL; const int N = 100005; const int P = 998244353; const LL MOD = 998244353; const int G = 3; const int NUM = 25; LL x1[MAXN]; LL x2[MAXN]; LL c[MAXN/4]; LL ans[MAXN/4]; LL wn[NUM]; LL quick_mod(LL a, LL b, LL m) { LL ans = 1; a %= m; while(b) { if(b & 1) { ans = ans * a % m; b--; } b >>= 1; a = a * a % m; } return ans; } void GetWn() { for(int i=0; i<NUM; i++) { int t = 1 << i; wn[i] = quick_mod(G, (P - 1) / t, P); } } void Rader(LL a[], int len) { int j = len >> 1; for(int i=1; i<len-1; i++) { if(i < j) swap(a[i], a[j]); int k = len >> 1; while(j >= k) { j -= k; k >>= 1; } if(j < k) j += k; } } void NTT(LL a[], int len, int on) { Rader(a, len); int id = 0; for(int h = 2; h <= len; h <<= 1) { id++; for(int j = 0; j < len; j += h) { LL w = 1; for(int k = j; k < j + h / 2; k++) { LL u = a[k] % P; LL t = w * (a[k + h / 2] % P) % P; a[k] = (u + t) % P; a[k + h / 2] = ((u - t) % P + P) % P; w = w * wn[id] % P; } } } if(on == -1) { for(int i = 1; i < len / 2; i++) swap(a[i], a[len - i]); LL Inv = quick_mod(len, P - 2, P); for(int i = 0; i < len; i++) a[i] = a[i] % P * Inv % P; } } void Conv(LL a[], LL b[], int n) { NTT(a, n, 1); NTT(b, n, 1); for(int i = 0; i < n; i++) a[i] = a[i] * b[i] % P; NTT(a, n, -1); } const int tN = 800000 + 5; long long F[tN], Finv[tN], inv[tN];//Fêǽ×3Ë£¬FinvêÇÄæÔaμĽ×3Ë void init(){ inv[1] = 1; for(long long i = 2; i < tN; i ++){ inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD; } F[0] = Finv[0] = 1; for(long long i = 1; i < tN; i ++){ F[i] = F[i-1] * 1ll * i % MOD; Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD; } } int main() { GetWn(); init(); int n,m; while (~scanf("%d",&n)){ for (int i = 0; i<=n; i++){ scanf("%I64d",&c[i]); } scanf("%d",&m); long long suma = 0; for (int i = 1;i<=m;i++){ long long a; scanf("%I64d",&a); suma = (suma - a+MOD) % MOD; } int len1 = n+1; int len = 1; while ( len < 2*len1 ) len <<= 1; for (int i = 0; i<len1 ; i++) x1[i] = c[n-i]*F[n-i]%MOD; for (int i = len1 ; i < len ;i++) x1[i] = 0; long long po = 1; for (int i = 0; i<len1 ; i++){ x2[i] = po*Finv[i]%MOD; po = ((po*suma) % MOD + MOD) % MOD; } for (int i = len1 ; i < len ;i++) x2[i] = 0; Conv(x1, x2, len); for (int i = 0 ; i<=n ; i++) ans[n-i] = (long long) (x1[i] + 0.5 ) % MOD; if (suma!=0) for (int i = 0;i<=n; i++) printf("%I64d ",(((ans[i]%MOD)*Finv[i])%MOD+MOD)%MOD); else for (int i = 0;i<=n; i++) printf("%I64d ",c[i]%MOD); puts(""); } return 0; }