#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> using namespace std; const double PI = acos(-1.0); struct complex{ double real,img; complex(double _real = 0,double _img = 0){ real = _real; img = _img; } }; complex operator +(const complex &a,const complex &b){ return complex(a.real+b.real,a.img+b.img); } complex operator -(const complex &a,const complex &b){ return complex(a.real-b.real,a.img-b.img); } complex operator *(const complex &a,const complex &b){ return complex(a.real*b.real-a.img*b.img,a.real*b.img+a.img*b.real); } void change(complex y[],int len){ int i,j,k; for(i=1,j=len/2;i<len-1;i++){ if(i<j) swap(y[i],y[j]);k=len/2; while(j>=k) j-=k,k/=2; if(j<k)j+=k; } } void FFT(complex y[],int len,int on){ change(y,len); complex t,u; for(int h=2;h<=len;h<<=1){ complex wn(cos(on*2*PI/h),sin(on*2*PI/h)); for(int j=0;j<len;j+=h){ complex w(1,0); for(int k=j;k<j+h/2;k++){ u=y[k]; t=w*y[k+h/2]; y[k]=u+t; y[k+h/2]=u-t; w=w*wn; } } } if(on==-1) for(int i=0;i<len;i++) y[i].real/=len; } #define N 300000 complex x1[N],x2[N]; void cal(char x[],int n,char y[],int m){ int i,c,L=max(n,m); for(i=0;i<n/2;i++) swap(x[i],x[n-1-i]); for(i=0;i<m/2;i++) swap(y[i],y[m-1-i]); for(i=1;i<2*L;i*=2); L=i; for(i=0;i<n;i++) x1[i].real=x[i]-'0',x1[i].img=0; for(;i<L;i++)x1[i].real=x1[i].img=0; for(i=0;i<m;i++) x2[i].real=y[i]-'0',x2[i].img=0; for(;i<L;i++)x2[i].real=x2[i].img=0; FFT(x1,L,1);FFT(x2,L,1); for(i=0;i<L;i++)x1[i]=x1[i]*x2[i]; FFT(x1,L,-1); for(i=c=n=0;i<L;i++){ c+=x1[i].real+0.5; x[i]=c%10+'0';if(c)n=i; c/=10; } if(c)x[++n]=c;x[++n]=0; for(i=0;i<n/2;i++) swap(x[i],x[n-1-i]); } char a[N],b[N]; int main(){ while(scanf("%s%s",a,b)!=EOF){ cal(a,strlen(a),b,strlen(b)); printf("%s\n",a); } return 0; }
多项式相乘整数运算版(效率较上面的提高了几倍):
#define CARRY 10000 #define CARRY_LEN 4 void cal(int x[],int &n,int y[],int m){ int i,L=max(n,m)*2; for(i=1;i<L;i<<=1); L=i; for(i=0;i<n;++i) x1[i].real=x[i],x1[i].img=0; for(;i<L;i++)x1[i].real=x1[i].img=0; for(i=0;i<m;++i) x2[i].real=y[i],x2[i].img=0; for(;i<L;++i) x2[i].real=x2[i].img=0; FFT(x1,L,1);FFT(x2,L,1); for(i=0;i<L;++i)x1[i]=x1[i]*x2[i]; FFT(x1,L,-1); long long c=0; for(i=n=0;i<L;++i){ c+=x1[i].real+0.5; x[i]=c%CARRY;if(c) n=i; c/=CARRY; } if(c) x[++n]=c; ++n; }