FFT能够快速解决卷积的问题,而这里的高精度乘法恰好就是这样,于是抄了个模板。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxl 200010
using namespace std;
int len1,len2,len;
int sum[maxl];
char ax[maxl],bx[maxl];
const double pi=acos(-1.0);
struct complex
{
double r,i;
complex(double r1=0.0,double i1=0.0)
{
r=r1;i=i1;
}
complex operator + (const complex &b)
{
return complex(r+b.r,i+b.i);
}
complex operator - (const complex &b)
{
return complex(r-b.r,i-b.i);
}
complex operator * (const complex &b)
{
return complex(r*b.r-i*b.i,r*b.i+i*b.r);
}
}x1[maxl],x2[maxl];
void change(complex y[],int len)
{
int i,j;
for(i=1,j=len/2;i<len-1;i++)
{
if(i<j)
swap(y[i],y[j]);
int 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);
for(int l=2;l<=len;l<<=1)
{
complex wn(cos(-on*2*pi/l),sin(-on*2*pi/l));
for(int j=0;j<len;j+=l)
{
complex w(1,0);
for(int k=j;k<j+l/2;k++)
{
complex u=y[k];
complex t=w*y[k+l/2];
y[k]=u+t;
y[k+l/2]=u-t;
w=w*wn;
}
}
}
if(on==-1)
for(int i=0;i<len;i++)
y[i].r/=len;
}
int main()
{
while(~scanf("%s%s",ax,bx))
{
len1=strlen(ax);len2=strlen(bx);
len=1;
while(len<len1*2 || len<len2*2)
len<<=1;
for(int i=0;i<len1;i++)
x1[i]=complex(ax[len1-i-1]-'0',0);
for(int i=len1;i<len;i++)
x1[i]=complex(0,0);
for(int i=0;i<len2;i++)
x2[i]=complex(bx[len2-i-1]-'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("%c",sum[i]+'0');
printf("\n");
}
return 0;
}