FFT板子。
将大整数看作多项式,它们的乘积即多项式的乘积在x=10处的取值。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define EPS 1e-8
const double PI = acos(-1.0);
struct Complex{
double real,image;
Complex(double _real,double _image){
real=_real;
image=_image;
}
Complex(){}
};
Complex operator + (const Complex &c1,const Complex &c2){
return Complex(c1.real+c2.real,c1.image+c2.image);
}
Complex operator - (const Complex &c1,const Complex &c2){
return Complex(c1.real-c2.real,c1.image-c2.image);
}
Complex operator * (const Complex &c1,const Complex &c2){
return Complex(c1.real*c2.real-c1.image*c2.image,c1.real*c2.image+c1.image*c2.real);
}
int rev(int id,int len){
int ret=0;
for(int i=0;(1<<i)<len;++i){
ret<<=1;
if(id&(1<<i)){
ret|=1;
}
}
return ret;
}
Complex tmp[200100];
//µ±DFT==1ʱÊÇDFT, DFT==-1ʱÔòÊÇÄæDFT
void IterativeFFT(Complex A[],int len, int DFT){//¶Ô³¤¶ÈΪlen(2µÄÃÝ)µÄÊý×é½øÐÐDFT±ä»»
for(int i=0;i<len;++i){
tmp[rev(i,len)]=A[i];
}
for(int i=0;i<len;++i){
A[i]=tmp[i];
}
for(int s=1;(1<<s)<=len;++s){
int m=(1<<s);
Complex wm=Complex(cos(DFT*2*PI/m),sin(DFT*2*PI/m));
for(int k=0;k<len;k+=m){//ÕâÒ»²ã½áµã°üº¬µÄÊý×éÔªËظöÊý¶¼ÊÇ(1<<s)
Complex w=Complex(1,0);
for(int j=0;j<(m>>1);++j){//ÕÛ°ëÒýÀí£¬¸ù¾ÝÁ½¸ö×Ó½Úµã¼ÆË㸸½Úµã
Complex t=w*A[k+j+(m>>1)];
Complex u=A[k+j];
A[k+j]=u+t;
A[k+j+(m>>1)]=u-t;
w=w*wm;
}
}
}
if(DFT==-1){
for(int i=0;i<len;++i){
A[i].real/=len;
A[i].image/=len;
}
}
}
Complex a[200100],b[200100];
int ans[200100];
char s1[50010],s2[50010];
int main(){
// freopen("a.in","r",stdin);
while(scanf("%s%s",s1,s2)!=EOF){
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(ans,0,sizeof(ans));
int len1=strlen(s1),len2=strlen(s2),len;
if((len1==1 && s1[0]=='0') || (len2==1 && s2[0]=='0')){
puts("0");
continue;
}
for(int i=0;;++i){
if((1<<i)>=len1+len2){
len=(1<<i);
break;
}
}
for(int i=len1-1,j=0;i>=0;--i,++j){
a[j]=Complex(s1[i]-'0',0);
}
for(int i=len2-1,j=0;i>=0;--i,++j){
b[j]=Complex(s2[i]-'0',0);
}
IterativeFFT(a,len,1);
IterativeFFT(b,len,1);
for(int i=0;i<len;++i){
a[i]=a[i]*b[i];
}
IterativeFFT(a,len,-1);
for(int i=0;i<len;++i){
ans[i]=(int)(a[i].real+0.5);
}
for(int i=0;i<len1+len2-1;++i){
ans[i+1]+=ans[i]/10;
ans[i]%=10;
}
for(int i=len;i>=0;--i){
if(ans[i]!=0){
for(int j=i;j>=0;--j){
printf("%d",ans[j]);
}
puts("");
break;
}
}
}
return 0;
}