fft.cpp GitHub #include "../template/includes.cpp" #include "../template/typedef.cpp" namespace { using complex = std::complex<ld>; std::vector<complex> FFT(const std::vector<complex> &a, int n) { ld theta = 2.0 * pi / n; const int len = a.size(); std::vector<complex> res = a; for (int m = len; m >= 2; m /= 2, theta *= 2) { for (int i = 0; i < m / 2; ++i) { for (int j = i; j < len; j += m) { int k = j + m / 2; complex x = res[j] - res[k]; res[j] += res[k]; res[k] = exp(i * theta * complex(0, 1)) * x; } } } for (int i = 0, j = 1; j < len - 1; ++j) { for (int k = len / 2; k > (i ^= k); k /= 2) ; if (j < i) std::swap(res[i], res[j]); } return res; } } // namespace std::vector<ll> convolution(const std::vector<ll> &lhs, const std::vector<ll> &rhs) { int n = 1, a = lhs.size(), b = rhs.size(); while (n < std::max(a, b) * 2) n <<= 1; std::vector<std::complex<ld>> ra(n), rb(n); for (int i = 0; i < n / 2; ++i) { if (i < a) ra[i] = std::complex<ld>(lhs[i], 0); if (i < b) rb[i] = std::complex<ld>(rhs[i], 0); } ra = FFT(ra, n); rb = FFT(rb, n); for (int i = 0; i < n; ++i) ra[i] *= rb[i]; ra = FFT(ra, -n); std::vector<ll> res(n); for (int i = 0; i < n; ++i) res[i] = ra[i].real() / n + 0.5; return res; } Includes includes.cpp typedef.cpp Back