This documentation is automatically generated by online-judge-tools/verification-helper
#define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod"
#include "../../fps/FPS_online_convolution.hpp"
#include <iostream>
using mint = atcoder::modint998244353;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int N, M;
std::cin >> N >> M;
int X = N + M - 1;
std::vector<int> A(X), B(X);
for (int i = 0; i < N; i++) std::cin >> A[i];
for (int i = 0; i < M; i++) std::cin >> B[i];
po167::FPS_online_convolution<mint> oc;
for (int i = 0; i < X; i++){
if (i) std::cout << " ";
std::cout << oc.query(A[i], B[i]).val();
}
std::cout << "\n";
}#line 1 "test/fps/online_fps.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod"
#line 2 "fps/FPS_online_convolution.hpp"
#include <atcoder/convolution>
namespace po167{
template<class T>
struct FPS_online_convolution{
std::vector<T> f, g, h, iz;
std::vector<std::vector<T>> f_inv, g_inv;
int p;
FPS_online_convolution() : f(0), g(0), h(0), iz(0), p(0){}
T query(T fi, T gi){
if (p == 0){
f = {fi};
g = {gi};
h = {fi * gi};
return h[p++];
}
int z = 0;
while ((p & (1 << z)) == 0) z++;
if (p == (1 << z)){
f.resize(p * 2, 0);
g.resize(p * 2, 0);
h.resize(p * 2, 0);
}
f[p] = fi;
g[p] = gi;
int l = p - (1 << z);
int m = p;
int r = p + (1 << z);
// [l, m) -> [m, r)
std::vector<T> tmp3(r - l);
if (l == 0){
f_inv.push_back({});
g_inv.push_back({});
iz.push_back((T)(1) / (T)(r - l));
}
for (int rp = 0; rp < 2; rp++){
std::swap(f, g);
std::swap(f_inv, g_inv);
if (l == 0 && rp == 1) break;
std::vector<T> tmp1(r - l), tmp2(r - l);
for (int i = l; i < m; i++){
tmp1[i - l] = f[i];
}
atcoder::internal::butterfly(tmp1);
if (l == 0) {
for (int i = 0; i < r - l; i++) {
if (i == 0) continue;
if (m <= i) break;
tmp2[i] = g[i];
}
atcoder::internal::butterfly(tmp2);
}
else{
if (g_inv[z].empty()){
g_inv[z].resize((1 << (z + 1)));
for (int i = 0; i < (1 << (z + 1)); i++){
if (i) g_inv[z][i] = g[i];
else g_inv[z][i] = 0;
}
atcoder::internal::butterfly(g_inv[z]);
}
tmp2 = g_inv[z];
}
for (int i = 0; i < r - l; i++) tmp3[i] += tmp1[i] * tmp2[i];
}
atcoder::internal::butterfly_inv(tmp3);
for (int i = m; i < r; i++) h[i] += tmp3[i - l] * iz[z];
h[p] += f[0] * g[p];
h[p] += f[p] * g[0];
return h[p++];
}
};
}
#line 5 "test/fps/online_fps.test.cpp"
#include <iostream>
using mint = atcoder::modint998244353;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int N, M;
std::cin >> N >> M;
int X = N + M - 1;
std::vector<int> A(X), B(X);
for (int i = 0; i < N; i++) std::cin >> A[i];
for (int i = 0; i < M; i++) std::cin >> B[i];
po167::FPS_online_convolution<mint> oc;
for (int i = 0; i < X; i++){
if (i) std::cout << " ";
std::cout << oc.query(A[i], B[i]).val();
}
std::cout << "\n";
}