// 1. 注意加减乘除写在struct里 且 加上&
// 2. w预处理不一定好,反而麻烦,我们只要连续
// 3. reverse可以代替-w
// 4. 注意rev的预处理,这个还是有点用的
#include <bits/stdc++.h>
#define I register int
#define F(i, a, b) for (I i = a; i <= b; i ++)
typedef double db;
const db pi = acos(- 1);
using namespace std;
int n, nn, Len, rev[M];
struct Z {
db x, y;
Z operator * (Z &a) { return Z{x * a.x - y * a.y, x * a.y + y * a.x}; }
Z operator + (Z &a) { return Z{x + a.x, y + a.y}; }
Z operator - (Z &a) { return Z{x - a.x, y - a.y}; }
} A[M], B[M];
void Dft(Z *A, I sig) {
F(i, 1, Len - 1)
if (i < rev[i]) swap(A[i], A[rev[i]]);
for (I m = 2; m <= Len; m <<= 1) {
Z w = Z{cos(2 * pi / m), sin(2 * pi / m)};
I half = m >> 1;
for (I i = 0; i < Len; i += m) {
Z o = Z{1, 0};
for (I j = i; j < i + half; j ++, o = o * w) {
Z u = A[j + half] * o;
A[j + half] = A[j] - u;
A[j] = A[j] + u;
}
}
}
if (sig == - 1) {
reverse(A + 1, A + Len);
F(i, 0, Len - 1)
A[i].x = int(A[i].x / Len + 0.5);
}
}
int main() {
// Do sth..
// nn is the length of A,B
for (Len = 1, cnt = 0; Len <= nn * 2; Len <<= 1, cnt ++);
F(i, 1, Len - 1)
rev[i] = (rev[i >> 1] >> 1) ^ (i & 1) * (Len >> 1);
Dft(A, 1), Dft(B, 1);
F(i, 0, Len - 1) A[i] = A[i] * B[i];
Dft(A, - 1);
}
fft卡常研究
最新推荐文章于 2020-03-18 14:09:25 发布