FFT之所以奇妙是因为它充分利用了旋转因子的周期性和对称性,加快了计算时间。
从叶子节点到根计算而不是从根节点递归求解大大节省了空间。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <algorithm> 5 using namespace std; 6 #define maxn 50050 7 #define PI acos(-1.0) 8 #define eps 0.001 9 char str[maxn]; 10 11 struct Complex{ 12 double a, b; 13 14 Complex(double _a=0.0,double _b=0.0):a(_a),b(_b){} 15 16 Complex operator + (const Complex &c) const{ 17 return Complex(a + c.a, b + c.b); 18 } 19 20 Complex operator - (const Complex &c) const{ 21 return Complex(a - c.a, b - c.b); 22 } 23 Complex operator * (const Complex &c) const{ 24 return Complex(a * c.a - b * c.b, a * c.b + b * c.a); 25 } 26 }; 27 28 Complex x[maxn * 4], y[maxn * 4]; 29 30 void change(Complex A[] , int len) { 31 for (int i = 1 , j = len / 2 ; i < len -1 ; i ++) { 32 if (i < j) swap(A[i], A[j]); 33 int k = len / 2; 34 while (j >= k) { 35 j -= k; 36 k /= 2; 37 } 38 if(j < k) j += k; 39 } 40 return ; 41 } 42 43 void FFT(Complex A[], int n, int flag){ 44 change(A, n); 45 for(int h = 2; h <= n; h <<= 1){ 46 Complex wn = Complex(cos(-flag * 2 * PI / h), sin(-flag * 2 * PI / h)); 47 for(int i = 0; i < n; i += h){ 48 Complex w = Complex(1, 0); 49 for(int j = i; j < i + h / 2; j++) 50 { 51 Complex s = Complex(A[j].a, A[j].b); 52 Complex t = w * A[j + h / 2]; 53 A[j] = s + t; 54 A[j + h / 2] = s - t; 55 w = w * wn; 56 } 57 } 58 } 59 if(flag == -1){ 60 for(int i = 0; i < n; i++) 61 { 62 A[i].a /= n; 63 } 64 } 65 return ; 66 } 67 68 int ans[maxn * 4]; 69 70 int main() 71 { 72 while(scanf("%s", str) != EOF) 73 { 74 int len1 = strlen(str); 75 76 for(int i = 0; i < len1; i++){ 77 x[i] = Complex(str[len1 - 1 - i] - '0', 0); 78 } 79 80 scanf("%s", str); 81 int len2 = strlen(str); 82 83 for(int i = 0; i < len2; i++){ 84 y[i] = Complex(str[len2 - 1 - i] - '0', 0); 85 } 86 87 int l1 = 1, l2 = 1; 88 while(l1 < len1 * 2){l1 <<= 1;} 89 while(l2 < len2 * 2){l2 <<= 1;} 90 int l = max(l1, l2); 91 for(int i = len1; i < l; i++){ 92 x[i] = Complex(0, 0); 93 } 94 for(int i = len2; i < l; i++){ 95 y[i] = Complex(0, 0); 96 } 97 FFT(x, l, 1); 98 FFT(y, l, 1); 99 for(int i = 0; i < l; i++){ 100 x[i] = x[i] * y[i]; 101 } 102 FFT(x, l, -1); 103 memset(ans, 0, sizeof(ans)); 104 int f = 0; 105 for(int i = 0; i < l; i++){ 106 int tmp = int(x[i].a + eps) + f; 107 ans[i] = tmp % 10; 108 f = tmp / 10; 109 } 110 int ok = 0; 111 l = len1 + len2; 112 while(ans[l] == 0 && l > 0) l--; 113 for(int i = l; i >= 0; i--){ 114 printf("%d", ans[i]); 115 } 116 printf("\n"); 117 } 118 return 0; 119 }