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.
题目大意:求A * B。
思路:快速傅里叶变换的模板题,偷的模板……也不知道使用姿势对不对QAQ。
代码(250MS):(Update:2014年11月16日)

1 #include <cmath> 2 #include <algorithm> 3 #include <cstdio> 4 #include <iostream> 5 #include <cstring> 6 #include <complex> 7 using namespace std; 8 typedef complex<double> Complex; 9 const double PI = acos(-1); 10 11 void fft_prepare(int maxn, Complex *&e) { 12 e = new Complex[2 * maxn - 1]; 13 e += maxn - 1; 14 e[0] = 1; 15 for (int i = 1; i < maxn; i <<= 1) 16 e[i] = Complex(cos(2 * PI * i / maxn), sin(2 * PI * i / maxn)); 17 for (int i = 3; i < maxn; i++) 18 if ((i & -i) != i) e[i] = e[i - (i & -i)] * e[i & -i]; 19 for (int i = 1; i < maxn; i++) e[-i] = e[maxn - i]; 20 } 21 /* f = 1: dft; f = -1: idft */ 22 void dft(Complex *a, int N, int f, Complex *e, int maxn) { 23 int d = maxn / N * f; 24 Complex x; 25 for (int n = N, m; m = n / 2, m >= 1; n = m, d *= 2) 26 for (int i = 0; i < m; i++) 27 for (int j = i; j < N; j += n) 28 x = a[j] - a[j + m], a[j] += a[j + m], a[j + m] = x * e[d * i]; 29 for (int i = 0, j = 1; j < N - 1; j++) { 30 for (int k = N / 2; k > (i ^= k); k /= 2); 31 if (j < i) swap(a[i], a[j]); 32 } 33 } 34 35 const int MAXN = 131072; 36 Complex x1[MAXN], x2[MAXN]; 37 char s1[MAXN / 2], s2[MAXN / 2]; 38 int sum[MAXN]; 39 40 int main() { 41 Complex* e = 0; 42 fft_prepare(MAXN, e); 43 while(scanf("%s%s",s1,s2) != EOF) { 44 int n1 = strlen(s1); 45 int n2 = strlen(s2); 46 int n = 1; 47 while(n < n1 * 2 || n < n2 * 2) n <<= 1; 48 for(int i = 0; i < n; ++i) { 49 x1[i] = i < n1 ? s1[n1 - 1 - i] - '0' : 0; 50 x2[i] = i < n2 ? s2[n2 - 1 - i] - '0' : 0; 51 } 52 53 dft(x1, n, 1, e, MAXN); 54 dft(x2, n, 1, e, MAXN); 55 for(int i = 0; i < n; ++i) x1[i] = x1[i] * x2[i]; 56 dft(x1, n, -1, e, MAXN); 57 for(int i = 0; i < n; ++i) x1[i] /= n; 58 59 for(int i = 0; i < n; ++i) sum[i] = round(x1[i].real()); 60 for(int i = 0; i < n; ++i) { 61 sum[i + 1] += sum[i] / 10; 62 sum[i] %= 10; 63 } 64 65 n = n1 + n2 - 1; 66 while(sum[n] <= 0 && n > 0) --n; 67 for(int i = n; i >= 0;i--) printf("%d", sum[i]); 68 puts(""); 69 } 70 }