便宜上,整数列 の範囲外の値を全て とします.和の範囲を定める条件 は
と同値なので, に対する は
と書き直せます. の累積和を で前計算しておけば,この式に従って各 に対する をそれぞれ で計算することができます. のときは
となり,こちらも の累積和を用いれば で計算できます.全体の計算量は となり本問の制約下で十分高速です.
xxxxxxxxxx
using namespace std;
using ll = long long;
constexpr ll MOD = 998244353;
int main() {
int n, m;
cin >> n >> m;
vector<ll> a(n + 1), b(m + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int j = 1; j <= m; j++) cin >> b[j];
vector<ll> acc(n + 2);
for (int i = 1; i <= n; i++) acc[i + 1] = (acc[i] + a[i]) % MOD;
vector<ll> c(n + 1);
for (int j = 1; j <= m; j++) {
c[0] = (c[0] + b[j] * acc[min(j, n + 1)]) % MOD;
}
for (int k = 1; k <= n; k++) {
for (int j = 1; j <= min(m, n / k); j++) {
c[k] = (c[k] + b[j] * (acc[min(j * (k + 1), n + 1)] - acc[j * k])) % MOD;
}
if (c[k] < 0) c[k] += MOD;
}
for (int k = 0; k <= n; k++) {
cout << c[k] << " \n"[k == n];
}
}