牛客國慶集訓派對Day4 F - NTT
阿新 • • 發佈:2018-10-31
題目連結:點選這裡
解題思路:
f(x)的i階導可以寫為:
那麼總的式子就是:
變換f(x)第i此導,使得式子對應第j位對應x的j次方的係數:
i+j>=n時a[i+j]=0,,沒影響.
設F(i)=a[i]*i!。
gd為g(x)的x的d次冪對應的係數是:
令i=i+j,那麼有:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int g = 3; const int mod = 998244353; const int mx = 1<<18; ll fac[mx],inv[mx],a[mx],b[mx]; int rev[mx],n; void init() { inv[0] = fac[0] = 1; inv[1] = fac[1] = 1; for(int i=2;i<mx;i++){ fac[i] = fac[i-1]*i%mod; inv[i] = (mod-mod/i)*inv[mod%i]%mod; } for(int i=2;i<mx;i++) inv[i] = inv[i]*inv[i-1]%mod; } void get_rev(int len) { for(int i=1;i<(1<<len);i++) rev[i] = (rev[i>>1]>>1)|((i&1)<<(len-1)); } ll qpow(ll x,ll y) { ll ans = 1; while(y){ if(y&1) ans = ans*x%mod; y >>= 1; x = x*x%mod; } return ans; } void ntt(ll *p,int len,int v) { for(int i=0;i<len;i++) if(i<rev[i]) swap(p[i],p[rev[i]]); for(int i=1;i<len;i<<=1){ ll tep = qpow(g,(mod-1)/(2*i)); if(v<0) tep = qpow(tep,mod-2); for(int j=0;j<len;j+=(i<<1)){ ll mul = 1; for(int k=j;k<i+j;k++){ ll x = p[k]; ll y = mul*p[k+i]%mod; p[k] = (x + y)%mod; p[k+i] = (x - y + mod)%mod; mul = mul*tep%mod; } } } if(v==-1){ ll invs = qpow(len,mod-2); for(int i=0;i<len;i++) p[i] = p[i]*invs%mod; } } int main() { init(); scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%lld",a+i); a[i] = a[i]*fac[i]%mod; b[i] = inv[i]; } int len = 1; while((1<<len)<2*n) len++; get_rev(len); len = 1<<len; ntt(a,len,1);ntt(b,len,1); for(int i=0;i<len;i++) a[i] = a[i]*a[i]%mod; for(int i=0;i<len;i++) b[i] = b[i]*b[i]%mod; ntt(a,len,-1);ntt(b,len,-1); for(int i=0;i<n;i++) printf("%lld%c",a[i+n-1]*b[i]%mod,i==n-1?'\n':' '); return 0; }