分治FFT/NTT
Posted hzoi-yzh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分治FFT/NTT相关的知识,希望对你有一定的参考价值。
考虑对当前左区间对右区间的贡献,由于右区间的F未更新,可以更改指标
egin{array}{rcl}
F_x&=&sumlimits_{i=L}^{mid}F_iG_{x-i}
&=&sumlimits_{i=L}^{x}F_iG_{x-i}
&=&sumlimits_{i=0}^{x-L}F_{L+i}G_{x-L-i}
end{array}
设$A_i=F_{i+L},B_i=G_i$
egin{array}{rcl}
F_x=C_{x-L}=sumlimits_{i=0}^{x-L}A_iB{x-L-i}
end{array}
模板:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #define ll long long 6 #define reg register 7 #define F(i,a,b) for(register int (i)=(a);(i)<=(b);++(i)) 8 using namespace std; 9 int read(); 10 const int N=400005; 11 const ll mod=998244353ll; 12 int n,h,cs; 13 int rev[N]; 14 ll ih; 15 ll f[N],g[N],a[N],b[N],omg[N],inv[N]; 16 ll qpow(ll x,ll b,ll mod=998244353ll,ll ans=1ll) 17 { 18 for(;b;b>>=1,x=x*x%mod) 19 if(b&1)ans=ans*x%mod; 20 return ans; 21 } 22 ll mo(ll x){return x>=mod?x-mod:x;} 23 void init(int len) 24 { 25 h=1,cs=0;while(h<=len)h<<=1,++cs; 26 ih=qpow(h,mod-2); 27 omg[0]=inv[0]=1ll;omg[1]=qpow(3,(mod-1)/h);inv[1]=qpow(omg[1],mod-2); 28 for(reg int i=0;i<h;++i){ 29 a[i]=b[i]=0; 30 rev[i]=(rev[i>>1]>>1)|((i&1)<<cs-1); 31 if(i>1)omg[i]=omg[i-1]*omg[1]%mod,inv[i]=inv[i-1]*inv[1]%mod; 32 } 33 } 34 void NTT(ll *a,ll *omg,int op) 35 { 36 for(reg int i=0;i<h;++i)if(i<rev[i])swap(a[i],a[rev[i]]); 37 for(reg int l=2,mid=1;l<=h;l<<=1,mid<<=1){ 38 for(ll *p=a;p!=a+h;p+=l) 39 for(reg int i=0;i<mid;++i){ 40 ll t=omg[h/l*i]*p[i+mid]%mod; 41 p[i+mid]=mo(p[i]-t+mod); 42 p[i]=mo(p[i]+t); 43 } 44 } 45 if(op==-1)for(reg int i=0;i<h;++i)a[i]=a[i]*ih%mod; 46 } 47 void solve(int l,int r) 48 { 49 if(l==r)return; 50 int mid=l+r>>1; 51 solve(l,mid); 52 int len=r-l+1; 53 init(len); 54 F(i,l,mid)a[i-l]=f[i]; 55 for(reg int i=0;i<len;++i)b[i]=g[i]; 56 NTT(a,omg,1);NTT(b,omg,1); 57 for(reg int i=0;i<h;++i)a[i]=a[i]*b[i]%mod; 58 NTT(a,inv,-1); 59 F(i,mid+1,r)f[i]=mo(f[i]+a[i-l]); 60 solve(mid+1,r); 61 } 62 int main() 63 { 64 n=read(); 65 F(i,1,n-1)g[i]=read(); 66 f[0]=1ll; 67 solve(0,n-1); 68 F(i,0,n-1)printf("%lld ",f[i]);puts(""); 69 return 0; 70 } 71 int read() 72 { 73 int x=0,fh=1;char tc=getchar(); 74 while(tc<‘0‘||tc>‘9‘){if(tc==‘-‘)fh=-1;tc=getchar();} 75 while(tc>=‘0‘&&tc<=‘9‘)x=(x<<3)+(x<<1)+(tc^48),tc=getchar(); 76 return fh*x; 77 }
以上是关于分治FFT/NTT的主要内容,如果未能解决你的问题,请参考以下文章