BZOJ 2179: FFT快速傅立叶

2179: FFT快速傅立叶

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 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

Sample Output

12

数据范围:
n<=60000

HINT

Source

[Submit][Status][Discuss]

 

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

posted @ 2016-12-23 10:59  YouSiki  阅读(166)  评论(0编辑  收藏  举报