#line 1 "b.cpp" #include #line 2 "/Users/Shared/po167_library/fps/FPS_add.hpp" #include namespace po167{ template // a(x) += b(x) * c * x^d void FPS_add(std::vector &a, std::vector b, T c = 1, int d = 0){ for (int i = 0; i < (int)(b.size()); i++){ while ((int)a.size() <= i + d) a.push_back((T)0); a[i + d] += b[i] * c; } } } #line 3 "b.cpp" namespace po167{ /* * return {res, prod L, prod R} * * res : * i = 0, 1, ... , N - 1 * sum L[0] * ... * L[i - 1] * f[i] * R[i + 1] * ... * R[N - 1] */ template std::tuple, std::vector, std::vector> divide_and_conquer_product(std::vector> f, std::vector> L, std::vector> R = {}){ int N = f.size(); assert(N == (int)L.size()); if (N == 0){ return {{}, {}, {}}; } auto calc = [&](auto self, int l, int r) -> void { if (l + 1 == r) return; int m = (l + r) / 2; self(self, l, m); self(self, m, r); if (!R.empty()){ f[l] = atcoder::convolution(f[l], R[m]); } else{ f[l] = atcoder::convolution(f[l], L[m]); } po167::FPS_add(f[l], atcoder::convolution(f[m], L[l])); L[l] = atcoder::convolution(L[l], L[m]); if (!R.empty()) R[l] = atcoder::convolution(R[l], R[m]); }; calc(calc, 0, N); return {f[0], L[0], (R.empty() ? L[0] : R[0])}; } } #line 4 "/Users/Shared/po167_library/fps/FPS_inv.hpp" namespace po167{ // return 1 / f template std::vector FPS_inv(std::vector f, int len = -1){ if (len == -1) len = f.size(); assert(f[0] != 0); std::vector g = {1 / f[0]}; int s = 1; while(s < len){ // g = 2g_s - f(g_s)^2 (mod x ^ (2 * s)) // g = g - (fg - 1)g // (fg - 1) = 0 (mod x ^ (s)) std::vector n_g(s * 2, 0); std::vector f_s(s * 2, 0); g.resize(s * 2); for (int i = 0; i < s * 2; i++){ if (int(f.size()) > i) f_s[i] = f[i]; n_g[i] = g[i]; } atcoder::internal::butterfly(g); atcoder::internal::butterfly(f_s); for (int i = 0; i < s * 2; i++){ f_s[i] *= g[i]; } atcoder::internal::butterfly_inv(f_s); T iz = 1 / (T)(s * 2); for (int i = s; i < s * 2; i++){ f_s[i] *= iz; } for (int i = 0; i < s; i++){ f_s[i] = 0; } atcoder::internal::butterfly(f_s); for (int i = 0; i < s * 2; i++){ f_s[i] *= g[i]; } atcoder::internal::butterfly_inv(f_s); for (int i = s; i < s * 2; i++){ n_g[i] -= f_s[i] * iz; } std::swap(n_g, g); s *= 2; } g.resize(len); return g; } } #line 39 "b.cpp" #include using mint = atcoder::modint998244353; using namespace std; int main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int N, M; cin >> N >> M; vector A(N); for (auto &a : A) cin >> a; std::vector> f(N); std::vector> L(N); for (int i = 0; i < N; i++){ f[i] = {1}; L[i] = {1, -A[i]}; } auto [tmp, l, r] = po167::divide_and_conquer_product(f, L); tmp = atcoder::convolution(tmp, po167::FPS_inv(l, M + 1)); for (int i = 1; i <= M; i++){ cout << (tmp[i]).val() << (i == M ? "\n" : " "); } }