FFT原理详解,包含大数乘法的代码
https://www.cnblogs.com/RabbitHu/p/FFT.html
多项式乘法:就是套一套板子:
#include<iostream> #include<cstdio> #include<cmath> using namespace std; #define ll long long #define N 2000005 struct complex{ double x,y; complex (double xx=0,double yy=0){x=xx,y=yy;} }; complex operator + (complex a,complex b){ return complex(a.x+b.x , a.y+b.y);} complex operator - (complex a,complex b){ return complex(a.x-b.x , a.y-b.y);} complex operator * (complex a,complex b){ return complex(a.x*b.x-a.y*b.y , a.x*b.y+a.y*b.x);} typedef complex cp; const double pi = acos(-1.0); inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } ll A[N],B[N],lena,lenb,n,res[N]; cp a[N],b[N],omg[N],inv[N]; void init(){//预处理出单位根及其倒数 for(register int i=0;i<n;i++) omg[i]=cp(cos(2*pi/n*i),sin(2*pi/n*i)); for(register int i=0;i<n;i++) inv[i]=cp(cos(2*pi/n*i),-sin(2*pi/n*i)); } void fft(cp *a, cp *omg){ int lim = 0; while((1<<lim)<n)lim++; //向下分治的次数 for(register int i=0;i<n;i++){ //先把系数移到最后一层递归的位置 int t=0; for(register int j=0;j<lim;j++) if((i>>j) & 1) t|=(1<<(lim-j-1)); if(i<t)swap(a[i],a[t]); } for(register int l=2;l<=n;l*=2){ //每个递归区间的长度 int m=l/2; for(cp *p=a;p!=a+n;p+=l) for(register int i=0;i<m;i++){//蝴蝶操作 cp t=omg[n/l*i]*p[i+m]; p[i+m]=p[i]-t; p[i]=p[i]+t; } } } //a0,a1,a2,a3...an int main(){ lena=read();lenb=read(); lena++;lenb++; n=1;while(n<lena+lenb)n<<=1; for(register int i=0;i<lena;i++)A[i]=read(); for(register int i=0;i<lenb;i++)B[i]=read(); for(register int i=0;i<lena;i++)a[i]=cp(A[i],0); for(register int i=0;i<lenb;i++)b[i]=cp(B[i],0); init(); fft(a,omg);fft(b,omg); for(register int i=0;i<n;i++)a[i]=a[i]*b[i]; fft(a,inv); for(register int i=0;i<n;i++) res[i]=floor(a[i].x/n+0.5); for(register int i=0;i<lena+lenb-1;i++) cout<<res[i]<<" "; }
多项式乘法的卷积形式