use proconio::input; const MOD: u64 = 998244353; fn pow_mod(mut base: u64, mut exp: u64, m: u64) -> u64 { let mut result = 1u64; base %= m; while exp > 0 { if exp & 1 == 1 { result = result * base % m; } exp >>= 1; base = base * base % m; } result } fn mod_inv(a: u64, m: u64) -> u64 { pow_mod(a, m - 2, m) } struct Convolution { w: Vec, iw: Vec, } impl Convolution { fn new() -> Self { let g: u64 = 3; let ig: u64 = 332748118; let w: Vec = (0..24).map(|i| pow_mod(g, (MOD - 1) >> i, MOD)).collect(); let iw: Vec = (0..24).map(|i| pow_mod(ig, (MOD - 1) >> i, MOD)).collect(); Convolution { w, iw } } fn fmt(&self, k: usize, a: &mut Vec) { for l in (1..=k).rev() { let d = 1 << (l - 1); let w = self.w[l]; let mut i = 0; while i < a.len() { let mut u = 1u64; for j in 0..d { let s = i + j; let x = a[s]; let y = a[s + d]; a[s] = (x + y) % MOD; a[s + d] = u * ((x + MOD - y) % MOD) % MOD; u = u * w % MOD; } i += d * 2; } } } fn ifmt(&self, k: usize, a: &mut Vec) { for l in 1..=k { let d = 1 << (l - 1); let w = self.iw[l]; let mut i = 0; while i < a.len() { let mut u = 1u64; for j in 0..d { let s = i + j; let y = a[s + d] * u % MOD; let x = a[s]; a[s] = (x + y) % MOD; a[s + d] = (x + MOD - y) % MOD; u = u * w % MOD; } i += d * 2; } } } fn convolve(&self, a: &[u64], b: &[u64]) -> Vec { let n0 = a.len() + b.len() - 1; if n0 == 1 { return vec![a[0] * b[0] % MOD]; } if a.len().min(b.len()) <= 50 { let mut res = vec![0u64; n0]; for (i, &ai) in a.iter().enumerate() { for (j, &bj) in b.iter().enumerate() { res[i + j] = (res[i + j] + ai * bj) % MOD; } } return res; } let k = (n0 as u64).next_power_of_two().trailing_zeros() as usize; let n = 1 << k; let mut a_ext = a.to_vec(); a_ext.resize(n, 0); let mut b_ext = b.to_vec(); b_ext.resize(n, 0); self.fmt(k, &mut a_ext); self.fmt(k, &mut b_ext); let mut c: Vec = (0..n).map(|i| a_ext[i] * b_ext[i] % MOD).collect(); self.ifmt(k, &mut c); let invn = mod_inv(n as u64, MOD); c.iter_mut().for_each(|x| *x = *x * invn % MOD); c.truncate(n0); c } } fn fps_inv(conv: &Convolution, f: &[u64], deg: usize) -> Vec { let mut res = vec![mod_inv(f[0], MOD)]; let mut d = 1usize; while d < deg { d <<= 1; let f_trunc: Vec = f.iter().take(d).cloned().collect(); let mut fg = conv.convolve(&res, &f_trunc); let ln = fg.len(); for i in 0..ln { fg[i] = (MOD - fg[i] % MOD) % MOD; } fg.resize(d, 0); fg[0] = (fg[0] + 2) % MOD; res = conv.convolve(&res, &fg); res.truncate(d); } res.truncate(deg); res } fn calc_g(conv: &Convolution, v: &[u64], m: usize) -> Vec { let n = v.len(); if n == 0 { return vec![0; m + 1]; } let deg = m + 2; let mut polys: Vec> = v .iter() .map(|&vi| vec![1, (MOD - vi % MOD) % MOD]) .collect(); while polys.len() > 1 { let mut new_polys = Vec::new(); let mut i = 0; while i < polys.len() { if i + 1 < polys.len() { let mut q_new = conv.convolve(&polys[i], &polys[i + 1]); if q_new.len() > deg { q_new.truncate(deg); } new_polys.push(q_new); } else { new_polys.push(polys[i].clone()); } i += 2; } polys = new_polys; } let mut q = polys.into_iter().next().unwrap(); q.truncate(deg); let q_deriv: Vec = (0..q.len().saturating_sub(1)) .map(|k| (k as u64 + 1) * q[k + 1] % MOD) .collect(); let neg_q_deriv: Vec = q_deriv.iter().map(|&x| (MOD - x % MOD) % MOD).collect(); let q_inv = fps_inv(conv, &q, m + 1); let s = conv.convolve(&neg_q_deriv, &q_inv); let mut result = vec![n as u64]; for i in 0..m { if i < s.len() { result.push(s[i]); } else { result.push(0); } } result } fn main() { input! { n: usize, m: usize, v: [u64; n], } let conv = Convolution::new(); let g = calc_g(&conv, &v, m); // メビウス関数 let mut mobius = vec![0i64; m + 1]; mobius[1] = 1; let mut spf: Vec = (0..=m).collect(); let sqrt_m = (m as f64).sqrt() as usize + 1; for i in 2..=sqrt_m { if spf[i] == i { let mut j = i * i; while j <= m { if spf[j] == j { spf[j] = i; } j += i; } } } for i in 2..=m { let p = spf[i]; let prev = i / p; if prev % p == 0 { mobius[i] = 0; } else { mobius[i] = -mobius[prev]; } } // 約数 let mut divisors: Vec> = vec![Vec::new(); m + 1]; for i in 1..=m { let mut j = i; while j <= m { divisors[j].push(i); j += i; } } // solve let mut res = Vec::with_capacity(m); for n in 1..=m { let mut f = 0u64; for &d in &divisors[n] { let mu = mobius[n / d]; if mu != 0 { let base = g[n / d]; let val = pow_mod(base, d as u64, MOD); if mu > 0 { f = (f + val) % MOD; } else { f = (f + MOD - val) % MOD; } } } res.push(f.to_string()); } println!("{}", res.join(" ")); }