A * B Problem Plus
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 11252 Accepted Submission(s): 1967
Problem Description
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.
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
Author
DOOM III
题意:大整数乘法
题解:大整数的长度非常大,一般的模拟会超时,要用fft才能过。。。忘记了输出0那里,wa了好久,可怜。。。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 200008
using namespace std;
const double pi = acos(-1.0);
struct mycomplex
{
double a,b;
mycomplex(double a_=0.0,double b_=0.0):a(a_),b(b_) {}
mycomplex operator + (const mycomplex &c) const
{
return mycomplex(a+c.a , b+c.b);
}
mycomplex operator - (const mycomplex &c) const
{
return mycomplex(a-c.a , b-c.b);
}
mycomplex operator * (const mycomplex &c) const
{
return mycomplex(a*c.a-b*c.b , a*c.b+b*c.a);
}
} a[maxn],b[maxn];
char s1[maxn],s2[maxn];
int res[maxn];
int init(char *s1,char *s2,mycomplex *a,mycomplex *b)
{
int len1=strlen(s1);
int len2=strlen(s2);
int len=1,i;
while(len<2*len1||len<2*len2) len<<=1;
for(i=0; i<len1; i++) a[i]=mycomplex(s1[len1-1-i]-'0',0);
for(; i<len; i++) a[i]=mycomplex(0,0);
for(i=0; i<len2; i++) b[i]=mycomplex(s2[len2-1-i]-'0',0);
for(; i<len; i++) b[i]=mycomplex(0,0);
return len;
}
void rader(mycomplex *f,int len)
{
int i,j,k;
for(i=1,j=len>>1; i<len-1; i++)
{
if(i<j) swap(f[i],f[j]);
k=len>>1;
while(j>=k)
{
j-=k;
k>>=1;
}
if(j<k) j+=k;
}
}
void fft(mycomplex *f,int len,int on)
{
rader(f,len);
for(int h=2; h<=len; h<<=1)
{
mycomplex wn(cos(-on*2*pi/h),sin(-on*2*pi/h));
for(int j=0; j<len; j+=h)
{
mycomplex w(1,0);
for(int k=j; k<j+h/2; k++)
{
mycomplex u = f[k];
mycomplex t = w*f[k+h/2];
f[k]=u+t;
f[k+h/2]=u-t;
w=w*wn;
}
}
}
if(on==-1) for(int i=0; i<len; i++) f[i].a/=len;
}
void myconvolution(mycomplex *a,mycomplex *b,int len,int *res)
{
fft(a,len,1); //求值,转化为点值表示
fft(b,len,1); //求值,转化为点值表示
for(int i=0; i<len; i++) a[i]=a[i]*b[i]; //点值相乘
fft(a,len,-1); //插值,转化为系数表示
for(int i=0; i<len; i++) res[i]=a[i].a+0.5;
}
void output(int *res,int len)
{
for(int i=0; i<len; i++)
{
res[i+1]+=res[i]/10;
res[i]=res[i]%10;
}
for(int i=len-1; i>=0; i--)
{
if(i==0&&!res[i]) printf("0");
else if(res[i])
for(; i>=0; i--) printf("%d",res[i]);
}
printf("\n");
}
int main()
{
int len;
while(scanf("%s%s",s1,s2)>0)
{
len=init(s1,s2,a,b);
myconvolution(a,b,len,res);
output(res,len);
}
return 0;
}