From c42d033dcc8bd7e24a94a5815d8df73bc0e885fc Mon Sep 17 00:00:00 2001 From: subcrip Date: Mon, 2 Sep 2024 19:00:05 +0800 Subject: [PATCH] Add number/fft.cc Signed-off-by: subcrip --- number/fft.cc | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 number/fft.cc diff --git a/number/fft.cc b/number/fft.cc new file mode 100644 index 0000000..49e17b5 --- /dev/null +++ b/number/fft.cc @@ -0,0 +1,48 @@ +void fft(vector>& y, bool idft) { + int n = y.size(); + vector rev(n); + for (int i = 0; i < n; ++i) { + rev[i] = rev[i >> 1] >> 1; + if (i & 1) { + rev[i] |= n >> 1; + } + } + for (int i = 0; i < n; ++i) { + if (i < rev[i]) { + swap(y[i], y[rev[i]]); + } + } + for (int h = 2; h <= n; h <<= 1) { + complex wn(cos(2 * M_PI / h), sin(2 * M_PI / h)); + for (int j = 0; j < n; j += h) { + complex w(1); + for (int k = j; k < j + h / 2; ++k) { + complex u = y[k], t = w * y[k + h / 2]; + y[k] = u + t; + y[k + h / 2] = u - t; + w *= wn; + } + } + } + if (idft) { + reverse(y.begin() + 1, y.end()); + for (int i = 0; i < n; ++i) { + y[i] /= n; + } + } +} + +vector multiply(const vector& a, const vector& b) { + vector> A(a.begin(), a.end()), B(b.begin(), b.end()); + int n = 1; + while (n < a.size() + b.size()) n <<= 1; + A.resize(n), B.resize(n); + fft(A, false), fft(B, false); + for (int i = 0; i < n; ++i) { + A[i] *= B[i]; + } + fft(A, true); + vector res(n); + transform(A.begin(), A.end(), res.begin(), expr(int(round(x.real())), auto&& x)); + return res; +}