Problem description
Link
计算A*B,其中A,B的位数不超过50000
Possible Solution
高精乘:时间复杂度O(n^2)
FFT :时间复杂度O(nlogn)
将A,B两数的每个位当做多项式A(X),B(X)的系数,计算出A(X)*B(X)的系数,在进行进位。记得到C
附代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define Maxlen 50005
const double PI = acos(-1.0);
struct complex{
double r,i;
complex(double _r = 0.0, double _i = 0.0): r(_r),i(_i) {}
};
complex operator * (complex &a, complex &b) {
return complex(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r);
}
complex operator + (complex &a, complex &b) {
return complex(a.r + b.r , a.i + b.i);
}
complex operator - (complex &a, complex &b) {
return complex(a.r - b.r , a.i - b.i);
}
class Solution{
private:
complex a[Maxlen], b[Maxlen];
int n;
int c[Maxlen*2];
public:
Solution(char *s1, char *s2) {
int len1 = strlen(s1);
for (int i = 0; i < len1; ++i)
a[i] = complex(s1[len1 - 1 - i] - '0', 0);
int len2 = strlen(s2);
for (int i = 0; i < len2; ++i)
b[i] = complex(s2[len2 - 1 - i] - '0', 0);
n = std::max(len1, len2)*2;
int x = 0;
while ((1<<x) < n) x++;
n = 1 << x;
for (;len1 < n; ++len1) a[len1] = complex(0,0);
for (;len2 < n; ++len2) b[len2] = complex(0,0);
}
void reverse(complex *a) {
for(int i = 1, j = n/2; i < n-1; i++) {
if(i < j) std::swap(a[i],a[j]);
int k = n/2;
for (;j >= k; j -= k,k /= 2);
if(j < k) j += k;
}
}
void fft(complex *a, int f) {
reverse(a);
for(int i = 2; i <= n; i <<= 1) {
complex wn(cos(-f*2*PI/i),sin(-f*2*PI/i));
for(int j = 0; j < n; j += i) {
complex w(1,0);
for(int k = j;k < j+i/2; k++) {
complex x = a[k];
complex y = w * a[k+i/2];
a[k] = x + y;
a[k+i/2] = x - y;
w = w * wn;
}
}
}
if(f == -1)
for(int i = 0; i < n; i++)
a[i].r /= n;
}
void solve() {
fft(a, 1);
fft(b, 1);
for (int i = 0; i < n; ++i)
a[i] = a[i] * b[i];
fft(a,-1);
int x = 0;
memset(c, 0, sizeof(c));
for (int i = 0; i < n; ++i) {
c[i] = (int)(a[i].r + 0.5) + x;
x = c[i] / 10;
c[i] = c[i] % 10;
}
n = 2*n;
while (c[n-1] <= 0 && n-1 > 0) --n;
while (n-1 >= 0) printf("%d", c[--n]);
printf("\n");
}
};
char s1[Maxlen], s2[Maxlen];
int main(){
while (scanf("%s", s1) != EOF){
scanf("%s", s2);
Solution solution(s1,s2);
solution.solve();
}
}