A * B Problem Plus
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 22061 Accepted Submission(s): 5501
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
- 数据量5w
- 简单乘法运算n^2复杂度显然不可行
- 现在将整数乘法看成变量x=10的多项式相乘
- 每一位上的数字为各项系数
- 用FFT计算卷积,把复杂度降到nlogn
- 详见代码FFT模板
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
typedef long long LL ;
typedef unsigned long long ULL ;
const int maxn = 140000 + 10;
const int inf = 0x3f3f3f3f ;
const int npos = -1 ;
const int mod = 1e9 + 7 ;
const int mxx = 100 + 5 ;
const double eps = 1e-6 ;
const double PI = acos(-1.0) ;
struct Complex{
double r, i;
Complex(double x=0.0, double y=0.0){
reset(x,y);
}
void reset(double x, double y){
r=x;
i=y;
}
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));
}
};
Complex A[maxn];
void FFT(Complex *a, int n, int op){
for(int i=0;i<n;i++){
int j=0;
for(int k=0;(1<<k)<n;k++){
j<<=1;
if(i & (1<<k))
j|=1;
}
A[j]=a[i];
}
for(int d=0;(1<<d)<n;d++){
int m=1<<d;
int m2=m<<1;
double p0=PI/m*op;
Complex unit_p0(cos(p0),sin(p0));
for(int i=0;i<n;i+=m2){
Complex unit(1,0);
for(int j=0;j<m;j++){
Complex &p1=A[i+j+m], &p2=A[i+j];
Complex t=unit*p1;
p1=p2-t;
p2=p2+t;
unit=unit*unit_p0;
}
}
}
if(-1==op)
for(int i=0;i<n;i++){
A[i].r/=n;
A[i].i/=n;
}
for(int i=0;i<n;i++)
a[i]=A[i];
}
Complex c[maxn], d[maxn];
char a[maxn], b[maxn];
int f[maxn], la, lb, n, sa, sb, flag;
int main(){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
while(~scanf("%s",a)){
la=strlen(a);
sa=0;
while((1<<sa)<la)sa++;
scanf("%s",b);
lb=strlen(b);
sb=0;
while((1<<sb)<lb)sb++;
n=1<<max(sa+1,sb+1);
for(int i=0;i<n;i++){
if(i<la){
c[i].reset(a[la-i-1]-'0',0);
}else{
c[i].reset(0,0);
}
if(i<lb){
d[i].reset(b[lb-i-1]-'0',0);
}else{
d[i].reset(0,0);
}
}
FFT(c,n,1);
FFT(d,n,1);
for(int i=0;i<n;i++)
c[i]=c[i]*d[i];
FFT(c,n,-1);
for(int i=0;i<n;i++)
f[i]=(int)(c[i].r+0.5);
for(int i=0;i<n-1;i++){
f[i+1]+=f[i]/10;
f[i]%=10;
}
flag=0;
for(int i=n-1;i>=0;i--){
if(f[i]){
printf("%d",f[i]);
flag=1;
}else if(flag || 0==i){
printf("0");
}
}
puts("");
}
return 0;
}