Skip to content

Commit b744262

Browse files
committed
快速傅立叶变换的迭代实现(附UOJ - 34 多项式乘法代码)
1 parent 1671645 commit b744262

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

Fast-Fourier-Transform(Iterative).cpp

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#include <cstdio>
2+
#include <cmath>
3+
4+
using namespace std;
5+
6+
struct complex
7+
{
8+
double re, im;
9+
complex(double _re = 0, double _im = 0) : re(_re), im(_im) { }
10+
complex operator + (const complex &x) { return complex(re + x.re, im + x.im); }
11+
complex operator - (const complex &x) { return complex(re - x.re, im - x.im); }
12+
complex operator * (const complex &x) { return complex(re * x.re - im * x.im, re * x.im + im * x.re); }
13+
};
14+
15+
int n, m, N, k;
16+
complex a[1 << 18], b[1 << 18], res_a[1 << 18], res_b[1 << 18];
17+
18+
int log2(int x)
19+
{
20+
int res = -1;
21+
while (x > 0)
22+
{
23+
res++;
24+
x >>= 1;
25+
}
26+
return res;
27+
}
28+
29+
inline int reverse(int x)
30+
{
31+
int res = 0;
32+
for (int i = 0; i <= k; i++)
33+
{
34+
if ((x & (1 << i)) != 0)
35+
{
36+
res |= (1 << (k - i));
37+
}
38+
}
39+
return res;
40+
}
41+
42+
void init(complex *a, complex *res)
43+
{
44+
for (int i = 0; i < N; i++)
45+
{
46+
res[reverse(i)] = a[i];
47+
}
48+
}
49+
50+
void dft(complex *a, complex *res, int inv)
51+
{
52+
init(a, res);
53+
for (int i = 2; i <= N; i <<= 1)
54+
{
55+
complex w0(cos(M_PI * 2 / i), inv * sin(M_PI * 2 / i));
56+
for (int j = 0; j < N; j += i)
57+
{
58+
complex w(1, 0);
59+
for (int k = j; k < j + (i >> 1); k++)
60+
{
61+
complex temp = res[k];
62+
res[k] = temp + res[k + (i >> 1)] * w;
63+
res[k + (i >> 1)] = temp - res[k + (i >> 1)] * w;
64+
w = w * w0;
65+
}
66+
}
67+
}
68+
}
69+
70+
int main()
71+
{
72+
scanf("%d%d", &n, &m);
73+
for (int i = 0; i <= n; i++)
74+
{
75+
scanf("%lf", &a[i].re);
76+
}
77+
for (int i = 0; i <= m; i++)
78+
{
79+
scanf("%lf", &b[i].re);
80+
}
81+
k = log2(m + n);
82+
N = 1 << (k + 1);
83+
dft(a, res_a, 1);
84+
dft(b, res_b, 1);
85+
for (int i = 0; i < N; i++)
86+
{
87+
a[i] = res_a[i] * res_b[i];
88+
}
89+
dft(a, res_a, -1);
90+
for (int i = 0; i <= n + m; i++)
91+
{
92+
printf("%d ", (int)((res_a[i].re / N) + 0.5));
93+
}
94+
return 0;
95+
}

0 commit comments

Comments
 (0)