wenbao与FFT
FFT入门模板
http://acm.hdu.edu.cn/showproblem.php?pid=1402
1 #include <iostream> 2 #include <string.h> 3 #include <cmath> 4 using namespace std; 5 6 const double PI = acos(-1.0); 7 8 //复数结构体 9 struct complex{ 10 double r, i; 11 complex(double _r = 0.0, double _i = 0.0) {r = _r, i = _i;} 12 complex operator + (const complex &a) { return complex(r+a.r, i+a.i); } 13 complex operator - (const complex &a) { return complex(r-a.r, i-a.i); } 14 complex operator * (const complex &a) { return complex(r*a.r-i*a.i, r*a.i+i*a.r); } 15 }; 16 /* 17 * 进行FFT和IFFT前的反转变换。 18 * 位置i和 (i二进制反转后位置)互换 19 * len必须去2的幂 20 */ 21 void change(complex y[], int len){ 22 for(int i = 1, j = len/2; i < len-1; ++i){ 23 if(i < j) swap(y[i], y[j]); 24 //交换互为小标反转的元素,i<j保证交换一次 25 //i做正常的+1,j左反转类型的+1,始终保持i和j是反转的 26 int k = len/2; 27 while(j >= k) j -= k, k /= 2; 28 if(j < k) j += k; 29 } 30 } 31 //on == 1 DFT on == -1 IDFT 32 void fft(complex y[], int len, int on){ 33 change(y, len); 34 for(int h = 2; h <= len; h <<= 1){ 35 complex wn(cos(-on*2*PI/h), sin(-on*2*PI/h)); 36 for(int j = 0; j < len; j += h){ 37 complex w(1, 0); 38 for(int k = j; k < j+h/2; ++k){ 39 complex u = y[k]; 40 complex t = w*y[k+h/2]; 41 y[k] = u + t; 42 y[k+h/2] = u - t; 43 w = w*wn; 44 } 45 } 46 } 47 if(on == -1) for(int i = 0; i < len; ++i) y[i].r /= len; 48 } 49 50 const int maxn = 2e5+10; 51 complex x1[maxn], x2[maxn]; 52 char str1[maxn/2], str2[maxn/2]; 53 int sum[maxn]; 54 55 int main(){ 56 while(~scanf("%s%s", str1, str2)){ 57 int len1 = strlen(str1), len2 = strlen(str2); 58 int len = 1; 59 while(len < len1*2 || len < len2*2) len <<= 1; 60 for(int i = 0; str1[i]; ++i) x1[i] = complex(str1[len1-i-1]-'0', 0); 61 for(int i = len1; i < len; ++i) x1[i] = complex(0, 0); 62 for(int i = 0; str2[i]; ++i) x2[i] = complex(str2[len2-i-1]-'0', 0); 63 for(int i = len2; i < len; ++i) x2[i] = complex(0, 0); 64 //求DFT 65 fft(x1, len, 1); 66 fft(x2, len, 1); 67 for(int i = 0; i < len; ++i) x1[i] = x1[i] * x2[i]; 68 fft(x1, len, -1); 69 for(int i = 0; i < len; ++i) sum[i] = (int)(x1[i].r+0.5); 70 for(int i = 0; i < len; ++i){ 71 sum[i+1] += sum[i]/10; 72 sum[i] %= 10; 73 } 74 len = len1 + len2 - 1; 75 while(sum[len] <= 0 && len > 0) --len; 76 for(int i = len; i >= 0; --i){ 77 printf("%d", sum[i]); 78 } 79 printf("\n"); 80 } 81 return 0; 82 }
只有不断学习才能进步!