BZOJ 2179: FFT快速傅立叶
2179: FFT快速傅立叶
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2923 Solved: 1498
[Submit][Status][Discuss]
Description
给出两个n位10进制整数x和y,你需要计算x*y。
Input
第一行一个正整数n。
第二行描述一个位数为n的正整数x。
第三行描述一个位数为n的正整数y。
Output
输出一行,即x*y的结果。
Sample Input
1
3
4
3
4
Sample Output
12
数据范围:
n<=60000
数据范围:
n<=60000
HINT
Source
FFT模板
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 5000005; 6 const double pi = acos(-1); 7 typedef complex<double> Complex; 8 9 int n, m, len; 10 int ans[maxn]; 11 int rev[maxn]; 12 char str[maxn]; 13 14 Complex a[maxn]; 15 Complex b[maxn]; 16 17 inline void calculateFFT(Complex *c, double f) 18 { 19 for (int i = 0; i < n; ++i) 20 if (i < rev[i])swap(c[i], c[rev[i]]); 21 22 for (int i = 1; i < n; i <<= 1) 23 { 24 Complex wn(cos(pi/i), f*sin(pi/i)); 25 26 for (int j = 0; j < n; j += (i << 1)) 27 { 28 Complex wk(1, 0); 29 30 for (int k = 0; k < i; ++k, wk *= wn) 31 { 32 Complex x = c[j + k]; 33 Complex y = c[i + j + k] * wk; 34 c[j + k] = x + y; 35 c[i + j + k] = x - y; 36 } 37 } 38 } 39 } 40 41 signed main(void) 42 { 43 scanf("%d", &n); 44 45 scanf("%s", str); 46 47 for (int i = 0; i < n; ++i) 48 a[i] = str[n - i - 1] - '0'; 49 50 scanf("%s", str); 51 52 for (int i = 0; i < n; ++i) 53 b[i] = str[n - i - 1] - '0'; 54 55 m = n << 1; 56 for (n = 1; n < m; ) 57 ++len, n <<= 1; 58 59 for (int i = 0; i < n; ++i) 60 { 61 rev[i] |= rev[i >> 1] >> 1; 62 rev[i] |= (i&1) << (len - 1); 63 } 64 65 calculateFFT(a, 1); 66 calculateFFT(b, 1); 67 68 for (int i = 0; i < n; ++i) 69 a[i] *= b[i]; 70 71 calculateFFT(a, -1); 72 73 for (int i = 0; i < n; ++i) 74 a[i] /= n; 75 76 for (int i= 0; i < m; ++i) 77 ans[i] = int(a[i].real() + 0.5); 78 79 while (!ans[m - 1])--m; 80 81 for (int i = 0; i < m; ++i) 82 if (ans[i] >= 10) 83 { 84 ans[i + 1] += ans[i]/10; 85 ans[i] %= 10; 86 } 87 88 if (!ans[m])--m; 89 90 for (int i = m; ~i; --i) 91 putchar('0' + ans[i]); 92 }
@Author: YouSiki