#pragma once #include <algorithm> #include <vector> #include "Mylib/Math/polynomial_taylor_shift.cpp" namespace haar_lib { template <typename T, const auto &convolve> std::vector<T> stirling_number_of_first_kind_fft(int N) { if (N == 0) return {1}; std::vector<int> p; { int a = N; while (a > 0) { if (a & 1) p.push_back(1); p.push_back(2); a >>= 1; } } std::vector<T> ret = {1}; std::reverse(p.begin(), p.end()); int t = 0; for (int x : p) { if (x == 1) { std::vector<T> a = {-t, 1}; ret = convolve(ret, a); t += 1; } else { auto s = polynomial_taylor_shift<T, convolve>(ret, -t); ret = convolve(ret, s); ret.resize(t * 2 + 1); t *= 2; } } ret.resize(N + 1); return ret; } } // namespace haar_lib
#line 2 "Mylib/Combinatorics/stirling_number_first_fft.cpp" #include <algorithm> #include <vector> #line 3 "Mylib/Math/polynomial_taylor_shift.cpp" namespace haar_lib { template <typename T, const auto &convolve> auto polynomial_taylor_shift(std::vector<T> a, T c) { const int N = a.size(); T f = 1; std::vector<T> A(2 * N - 1); for (int i = 0; i < N; ++i) { if (i) f *= i; A[i + N - 1] = a[i] * f; } T d = 1; std::vector<T> g(N); g[N - 1] = f.inv(); for (int i = N - 2; i >= 0; --i) g[i] = g[i + 1] * (i + 1); std::vector<T> B(2 * N - 1); for (int i = 0; i < N; ++i) { B[N - i - 1] = d * g[i]; d *= c; } auto C = convolve(A, B); std::vector<T> ret(N); for (int i = 0; i < N; ++i) ret[i] = C[(N - 1) * 2 + i] * g[i]; return ret; } } // namespace haar_lib #line 5 "Mylib/Combinatorics/stirling_number_first_fft.cpp" namespace haar_lib { template <typename T, const auto &convolve> std::vector<T> stirling_number_of_first_kind_fft(int N) { if (N == 0) return {1}; std::vector<int> p; { int a = N; while (a > 0) { if (a & 1) p.push_back(1); p.push_back(2); a >>= 1; } } std::vector<T> ret = {1}; std::reverse(p.begin(), p.end()); int t = 0; for (int x : p) { if (x == 1) { std::vector<T> a = {-t, 1}; ret = convolve(ret, a); t += 1; } else { auto s = polynomial_taylor_shift<T, convolve>(ret, -t); ret = convolve(ret, s); ret.resize(t * 2 + 1); t *= 2; } } ret.resize(N + 1); return ret; } } // namespace haar_lib