分析:网上别家的代码都分析的很好,我只是给我自己贴个代码,我是kuangbin的搬运工
一点想法:其实FFT就是快速求卷积罢了,当小数据的时候我们完全可以用母函数来做,比如那种硬币问题
FFT只是用来解决数据规模较大时的办法,可以达到nlogn的效率,大体原理就是运用了n次单位复根的折半引理
具体可以看算法导论
高度仰慕kuangbin大神的模板,实在是不想自己写
对于这个题,我们10^k的系数看成多项式系数,然后求卷积,进位就好了
#include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <vector> #include <math.h> #include <map> using namespace std; typedef long long LL; const int INF=0x3f3f3f3f; const int N=2e5+5; const double pi = acos(-1.0); struct complex{ double r,i; complex(double R=0,double I=0){ r=R;i=I; } complex operator+(const complex &a)const{ return complex(r+a.r,i+a.i); } complex operator-(const complex &a)const{ return complex(r-a.r,i-a.i); } complex operator*(const complex &a)const{ return complex(r*a.r-i*a.i,r*a.i+i*a.r); } }; void change(complex x[],int len){ int i,j,k; for(i=1,j=len/2;i<len-1;++i){ if(i<j)swap(x[i],x[j]); k=len/2; while(j>=k){j-=k;k>>=1;} if(j<k)j+=k; } } void fft(complex x[],int len,int on){ change(x,len); for(int i=2;i<=len;i<<=1){ complex wn(cos(-on*2*pi/i),sin(-on*2*pi/i)); for(int j=0;j<len;j+=i){ complex w(1,0); for(int k=j;k<j+i/2;++k){ complex u = x[k]; complex t = w*x[k+i/2]; x[k]=u+t; x[k+i/2]=u-t; w=w*wn; } } } if(on==-1)for(int i=0;i<len;++i)x[i].r/=len; } complex x1[N],x2[N]; char str1[N/2],str2[N/2]; int sum[N]; int main(){ while(~scanf("%s%s",str1,str2)){ int len1 = strlen(str1); int len2 = strlen(str2),len=1; while(len<len1*2||len<len2*2)len<<=1; for(int i=0;i<len1;++i) x1[i]=complex(str1[len1-1-i]-'0',0); for(int i=len1;i<len;++i) x1[i]=complex(0,0); for(int i=0;i<len2;++i) x2[i]=complex(str2[len2-1-i]-'0',0); for(int i=len2;i<len;++i) x2[i]=complex(0,0); fft(x1,len,1); fft(x2,len,1); for(int i=0;i<len;++i) x1[i]=x1[i]*x2[i]; fft(x1,len,-1); for(int i=0;i<len;++i) sum[i]=(int)(x1[i].r+0.5); for(int i=0;i<len;++i){ sum[i+1]+=sum[i]/10; sum[i]%=10; } len = len1+len2-1; while(sum[len]<=0&&len>0)--len; for(int i=len;i>=0;--i)printf("%d",sum[i]); printf(" "); } return 0; }