FFT&NTT模板
Posted yiqiatiya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FFT&NTT模板相关的知识,希望对你有一定的参考价值。
博主菜鸡,只会背模板,根本解释不来嘤嘤嘤~
FFT:
#include<bits/stdc++.h> #define IL inline #define LF double using namespace std; const int N=5e6+5; const LF Pi=acos(-1.0); struct com{ LF x,y; com(LF xx=0,LF yy=0){x=xx,y=yy;} com operator+(const com &a) const{return com(a.x+x,a.y+y);} com operator-(const com &a) const{return com(x-a.x,y-a.y);} com operator*(const com &a) const{return com(x*a.x-y*a.y,a.x*y+a.y*x);} }a[N],b[N]; IL int in(){ char c;int f=1; while((c=getchar())<‘0‘||c>‘9‘) if(c==‘-‘) f=-1; int x=c-‘0‘; while((c=getchar())>=‘0‘&&c<=‘9‘) x=x*10+c-‘0‘; return x*f; } int n,m,r[N],Max=1,cnt; void FFT(com *a,int op){ for(int i=0;i<Max;++i) if(i<r[i]) swap(a[i],a[r[i]]); for(int i=1;i<Max;i<<=1){ com Wn=com(cos(Pi/i),op*sin(Pi/i)); for(int k=i<<1,j=0;j<Max;j+=k){ com w=com(1,0); for(int l=0;l<i;++l,w=w*Wn){ com x=a[j+l],y=w*a[j+i+l]; a[j+l]=x+y,a[j+i+l]=x-y; } } } } int main() { n=in(),m=in(); while(Max<=n+m) Max<<=1,++cnt; for(int i=0;i<Max;++i) r[i]=(r[i>>1]>>1)|((i&1)<<cnt-1); for(int i=0;i<=n;++i) a[i].x=in(); for(int i=0;i<=m;++i) b[i].x=in(); FFT(a,1),FFT(b,1); for(int i=0;i<=Max;++i) a[i]=a[i]*b[i]; FFT(a,-1); for(int i=0;i<=n+m;++i) printf("%d ",(int)(a[i].x/Max+0.5)); return 0; }
NTT:
#include<bits/stdc++.h> #define IL inline #define LL long long using namespace std; const LL P=998244353,G=3,Gi=332748118,N=4e6+3; LL n,m,a[N],b[N]; int r[N],Max=1,cnt; IL int in(){ char c;int f=1; while((c=getchar())<‘0‘||c>‘9‘) if(c==‘-‘) f=-1; int x=c-‘0‘; while((c=getchar())>=‘0‘&&c<=‘9‘) x=x*10+c-‘0‘; return x*f; } IL LL ksm(LL a,LL b){ LL c=1; while(b){ if(b&1) c=c*a%P;a=a*a%P; b>>=1; } return c; } void NTT(LL *a,int op){ for(int i=0;i<Max;++i) if(i<r[i]) swap(a[i],a[r[i]]); for(int i=1;i<Max;i<<=1){ LL wn=ksm(~op?G:Gi,(P-1)/(i<<1)); for(int j=0;j<Max;j+=(i<<1)){ LL w=1; for(int k=0;k<i;++k,w=wn*w%P){ LL x=a[j+k],y=w*a[j+i+k]%P; a[j+k]=(x+y)%P,a[j+i+k]=(x-y+P)%P; } } } } int main() { n=in(),m=in(); for(int i=0;i<=n;++i) a[i]=(in()+P)%P; for(int i=0;i<=m;++i) b[i]=(in()+P)%P; while(Max<=n+m) Max<<=1,++cnt; for(int i=0;i<Max;++i) r[i]=(r[i>>1]>>1)|((i&1)<<cnt-1); NTT(a,1),NTT(b,1); for(int i=0;i<Max;++i) a[i]=a[i]*b[i]%P;NTT(a,-1); LL inv=ksm(Max,P-2); for(int i=0;i<=n+m;++i) printf("%lld ",(a[i]*inv)%P); return 0; }
以上是关于FFT&NTT模板的主要内容,如果未能解决你的问题,请参考以下文章
hihocoder #1388 : Periodic Signal NTT&FFT