HDU1402:A * B Problem Plus(FFT与大数乘法)
Calculate A * B. Input Each line will contain two integers A and B. Process to end of file. Note: the length of each integer will not exceed 50000. Output For each case, output A * B in one line. Sample Input 1 2 1000 2 Sample Output 2 2000
把每一位看成ai*10^i,然后就是两个多项式相乘。利用FFT,把复杂度降到O(nlogn)。
#include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=200010; const double pi=acos(-1.0); struct complex { double r,i; complex(){}; complex(double rr,double ii):r(rr),i(ii){} complex friend operator +(complex a,complex b){ return complex(a.r+b.r,a.i+b.i); } complex friend operator -(complex a,complex b) { return complex(a.r-b.r,a.i-b.i);} complex friend operator *(complex a,complex b) { return complex(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);} }tmp[maxn]; struct DFT{ complex a[maxn]; void fft(int sz,int bg,int step,int opt){ if(sz==1) return; int m=sz>>1; fft(m,bg,step<<1,opt); fft(m,bg+step,step<<1,opt); complex w=complex(1,0),t=complex(cos(2.0*pi/sz),sin(2.0*pi*opt/sz)); for(int k=0;k<m;k++) { int pos=2*step*k; tmp[k]=a[pos+bg]+w*a[pos+bg+step]; tmp[k+m]=a[pos+bg]-w*a[pos+bg+step]; w=w*t; } for(int i=0;i!=sz;i++) a[i*step+bg]=tmp[i]; } }A,B; char c[maxn]; int ans[maxn+10]; int main() { while(~scanf("%s",c)){ int L1=strlen(c),L2,len=1; for(int i=0;i<L1;i++) A.a[i].r=c[L1-i-1]-'0',A.a[i].i=0; scanf("%s",c); L2=strlen(c); for(int i=0;i<L2;i++) B.a[i].r=c[L2-i-1]-'0',B.a[i].i=0; while(len<L1+L2+2) len<<=1; for(int i=L1;i<=len;i++) A.a[i].r=A.a[i].i=0; for(int i=L2;i<=len;i++) B.a[i].r=B.a[i].i=0; A.fft(len,0,1,1); B.fft(len,0,1,1); for(int i=0;i<len;i++) A.a[i]=A.a[i]*B.a[i]; A.fft(len,0,1,-1); int head=0; for(int i=0;i<len;i++) ans[i]=(int)(A.a[i].r/len+0.5); for(int i=0;i<len;i++){ ans[i+1]+=ans[i]/10; ans[i]%=10; if(ans[i]>0) head=i; } for(int i=head;i>=0;i--) printf("%d",ans[i]); printf("\n"); } return 0; }
It is your time to fight!