大数乘法
自己的代码tle,快速傅里叶变换没弄懂:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
__int64 sum1[13550],sum2[13550];
__int64 sum[13550];
void fun(char *str1,char *str2)
{
int num1=0,len=strlen(str1),num2=0;;
for(char *p=str1+len-6;p>str1;*p='\0',p-=6)
sum1[num1++]=atoi(p);
sum1[num1]=atoi(str1);
len=strlen(str2);
for(char *p=str2+len-6;p>str2;*p='\0',p-=6)
sum2[num2++]=atoi(p);
sum2[num2]=atoi(str2);
int i,j,num;
memset(sum,0,sizeof(sum));
for(i=0;i<=num1;i++)
for(j=0,num=i;j<=num2;j++)
{
sum[num]+=sum1[i]*sum2[j];
sum[num+1]+=sum[num]/1000000;
sum[num]%=1000000;
num++;
}
while(sum[num]==0) num--;
if(num<0) {printf("0\n");return ;}
printf("%I64d",sum[num--]);
for(;num>=0;num--)
printf("%06I64d",sum[num]);
printf("\n");
}
int main()
{
char str1[50050],str2[50050];
while(~scanf("%s",str1))
{
scanf(" %s",str2);
if(str2[0]=='0'||str1[0]=='0') {printf("0\n");continue;}
fun(str1,str2);
}
return 0;
}
下面代码贴别人的
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const double PI= acos(-1.0);
struct vir
{
double re,im; //实部和虚部
vir(double a=0,double b=0){
re=a; im=b;
}
vir operator +(const vir &b){
return vir(re+b.re,im+b.im);
}
vir operator -(const vir &b){
return vir(re-b.re, im-b.im);
}
vir operator *(const vir &b){
return vir(re*b.re-im*b.im , re*b.im+im*b.re);
}
};
vir x1[200005],x2[200005];
void change(vir *x,int len,int loglen)
{
int i,j,k,t;
for(i=0;i<len;i++)
{
t=i;
for(j=k=0; j<loglen; j++,t>>=1)
k= (k<<1)|(t&1);
if(k<i){
vir wt=x[k];
x[k]=x[i];
x[i]=wt;
}
}
}
void fft(vir *x,int len,int loglen)
{
int i,j,t,s,e;
change(x,len,loglen);
t=1;
for(i=0;i<loglen;i++,t<<=1)
{
s=0; e=s+t;
while(s<len)
{
vir a,b,wo(cos(PI/t),sin(PI/t)),wn(1,0);
for(j=s;j<s+t;j++)
{
a=x[j]; b=x[j+t]*wn;
x[j]=a+b; x[j+t]=a-b;
wn=wn*wo;
}
s=e+t; e=s+t;
}
}
}
void dit_fft(vir *x,int len,int loglen)
{
int i,j,s,e,t=1<<loglen;
for(i=0;i<loglen;i++)
{
t>>=1;
s=0; e=s+t;
while(s<len)
{
vir a,b,wn(1,0),wo(cos(PI/t),-sin(PI/t));
for(j=s;j<s+t;j++)
{
a=x[j]+x[j+t]; b=(x[j]-x[j+t])*wn;
x[j]=a; x[j+t]=b;
wn=wn*wo;
}
s=e+t; e=s+t;
}
}
change(x,len,loglen);
for(i=0;i<len;i++)
x[i].re/=len;
}
int main()
{
char a[100005],b[100005];
int i,len1,len2,len,loglen;
int t,over;
while(scanf("%s%s",a,b)!=EOF)
{
len1=strlen(a)<<1;
len2=strlen(b)<<1;
len=1;
loglen=0;
while(len<len1)
len<<=1, loglen++;
while(len<len2)
len<<=1, loglen++;
//init
for(i=0;a[i];i++)
x1[i].re=a[i]-'0', x1[i].im=0;
for(;i<len;i++)
x1[i].re=x1[i].im=0;
for(i=0;b[i];i++)
x2[i].re=b[i]-'0', x2[i].im=0;
for(;i<len;i++)
x2[i].re=x2[i].im=0;
fft(x1,len,loglen);
fft(x2,len,loglen);
for(i=0;i<len;i++)
x1[i] = x1[i]*x2[i];
dit_fft(x1,len,loglen);
//将x1.re从浮点数转化为十进制整型存入a
for(i=(len1+len2)/2-2,over=len=0;i>=0;i--)
{
t=x1[i].re+over+0.5;
a[len++]= t%10;
over = t/10;
}
while(over){
a[len++]=over%10;
over/=10;
}
for(len--;len>=0&&!a[len];len--);
if(len<0)
putchar('0');
else
for(;len>=0;len--)
putchar(a[len]+'0');
putchar('\n');
}
return 0;
}