#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
const ll mod = 998244353, g = 3;
ll pow(ll a, ll b) {
ll ans = 1;
while (b != 0) {
if ((b & 1) == 1) {
ans = ans * a % mod;
}
a = a * a % mod;
b = b / 2;
}
return ans;
}
void swap(ll & a, ll & b) {
a ^= b ^= a ^= b;
}
class Poly {
private:
vector < ll > rev;
void get_rev() {
rev.resize(n);
rev[0] = 0;
for (int i = 0; i < n; i++) {
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (len - 1));
}
}
public:
vector < ll > a;
int len, n;
Poly() {
len = 0;
n = 1;
a.push_back(0);
get_rev();
}
void set_length(int len_, bool clear = false) {
if (clear) {
a.resize(1 << len_);
} else {
if (len < len_) {
a.insert(a.end(), (1 << len_) - n, 0);
} else {
a.erase(a.begin() + (1 << len_), a.end());
}
}
n = 1 << len_;
len = len_;
get_rev();
}
ll & operator [] (const int & i) {
return a[i];
}
ll operator [] (const int & i) const {
return a[i];
}
void NTT(int inv) {
for (int i = 0; i < n; i++) {
if (rev[i] < i) {
swap(a[i], a[rev[i]]);
}
}
for (int mid = 1; mid < n; mid <<= 1) {
ll omega = pow(g, (mod - 1) / (2 * mid));
if (inv == -1) {
omega = pow(omega, mod - 2);
}
for (int i = 0; i < n; i += 2 * mid) {
ll w = 1;
for (int j = 0; j < mid; j++, w = w * omega % mod) {
ll x = a[i + j];
ll y = a[i + mid + j] * w % mod;
a[i + j] = (x + y) % mod;
a[i + mid + j] = (x - y + mod) % mod;
}
}
}
if (inv == -1) {
ll inv_n = pow(n, mod - 2);
for (int i = 0; i < n; i++) {
a[i] = a[i] * inv_n % mod;
}
}
}
};
void print(const Poly & a) {
for (int i = 0; i < a.n; i++) {
printf("%lld ", a[i]);
}
putchar(10);
}
Poly set_length(const Poly & a, const int & len) {
static Poly b;
b = a;
b.set_length(len);
return b;
}
void unify_length(const Poly & a, const Poly & b, Poly & x, Poly & y, Poly & c) {
x = a;
x.set_length(max(a.len, b.len));
y = b;
y.set_length(max(a.len, b.len));
c.set_length(max(a.len, b.len), true);
}
Poly Add(const Poly & a, const Poly & b) {
static Poly x, y, c;
unify_length(a, b, x, y, c);
for (int i = 0; i < x.n; i++) {
c[i] = (x[i] + y[i]) % mod;
}
return c;
}
Poly Sub(const Poly & a, const Poly & b) {
static Poly x, y, c;
unify_length(a, b, x, y, c);
for (int i = 0; i < x.n; i++) {
c[i] = (x[i] - y[i] + mod) % mod;
}
return c;
}
Poly Mult(const Poly & a, const ll & b) {
static Poly c;
c = a;
for (int i = 0; i < c.n; i++) {
c[i] = c[i] * b % mod;
}
return c;
}
Poly Mult(const ll & b, const Poly & a) {
static Poly c;
c = a;
for (int i = 0; i < c.n; i++) {
c[i] = c[i] * b % mod;
}
return c;
}
Poly Mult(const Poly & a, const Poly & b) {
static Poly x, y, c;
unify_length(a, b, x, y, c);
x.set_length(x.len + 1);
y.set_length(y.len + 1);
c.set_length(c.len + 1);
x.NTT(1);
y.NTT(1);
for (int i = 0; i < x.n; i++) {
c[i] = x[i] * y[i] % mod;
}
c.NTT(-1);
return c;
}
Poly MultMod(const Poly & a, const Poly & b) {
static Poly c;
c = Mult(a, b);
c.set_length(c.len - 1);
return c;
}
Poly Inverse(const Poly & a) {
static Poly ans[2];
ans[0].set_length(0);
ans[0][0] = pow(a[0], mod - 2);
for (int i = 1, t; i <= a.len; i++) {
t = i & 1;
ans[t] = Sub(Mult(ans[t ^ 1], 2), MultMod(Mult(ans[t ^ 1], ans[t ^ 1]), set_length(a, i)));
}
return ans[a.len & 1];
}
Poly Differential(const Poly & a) {
static Poly b;
b.set_length(a.len);
for (int i = a.n - 1; i > 0; i--) {
b[i - 1] = a[i] * i % mod;
}
return b;
}
Poly Integral(const Poly & a) {
static Poly b;
b.set_length(a.len);
for (int i = 1; i < a.n; i++) {
b[i] = a[i - 1] * pow(i, mod - 2) % mod;
}
return b;
}
Poly Natural_Log(const Poly & a) {
return Integral(MultMod(Differential(a), Inverse(a)));
}
Poly Exp(const Poly & a) {
static Poly ans[2], one;
ans[0].set_length(0);
ans[0][0] = 1;
for (int i = 1, t; i <= a.len; i++) {
t = i & 1;
ans[t ^ 1].set_length(i);
one.set_length(i);
one[0] = 1;
ans[t] = Mult(ans[t ^ 1], Add(Sub(one, Natural_Log(ans[t ^ 1])), a));
}
return ans[a.len & 1];
}
Poly __Power(const Poly & a, const ll & k) {
return Exp(Mult(Natural_Log(a), k));
}
Poly Power(const Poly & a, const ll & k0, const ll & k1, const ll & k2) {
static Poly temp, one;
int t = -1;
ll b;
for (int i = 0; i < a.n; i++) {
if (a[i] != 0) {
t = i;
b = a[i];
break;
}
}
if (t * k2 >= a.n || t == -1) {
one.set_length(a.len);
return one;
}
temp = a;
for (int i = t; i < temp.n; i++) {
temp[i - t] = temp[i];
}
for (int i = temp.n - t; i < temp.n; i++) {
temp[i] = 0;
}
ll inv_b = pow(b, mod - 2);
for (int i = 0; i < temp.n; i++) {
temp[i] = temp[i] * inv_b % mod;
}
temp = __Power(temp, k0);
ll b_k = pow(b, k1);
for (int i = 0; i < temp.n; i++) {
temp[i] = temp[i] * b_k % mod;
}
for (int i = temp.n - t * k0 - 1; i >= 0; i--) {
temp[i + t * k0] = temp[i];
}
for (int i = 0; i < t * k0 && i < temp.n; i++) {
temp[i] = 0;
}
return temp;
}
int get_length(int n) {
for (int i = 0; ; i++) {
if (n <= (1 << i)) {
return i;
}
}
}
int main() {
Poly a;
int n;
scanf("%d", &n);
ll k0 = 0, k1 = 0, k2 = 0;
int c;
do {
c = getchar();
} while ('0' > c || c > '9');
do {
k0 = ((k0 * 10) + (c ^ 48)) % mod;
k1 = ((k1 * 10) + (c ^ 48)) % (mod - 1);
if ((k2 * 10) + (c ^ 48) <= mod) {
k2 = (k2 * 10) + (c ^ 48);
}
c = getchar();
} while ('0' <= c && c <= '9');
a.set_length(get_length(n));
for (int i = 0; i < n; i++) {
scanf("%lld", &a[i]);
}
Poly b;
b = Power(a, k0, k1, k2);
for (int i = 0; i < n; i++) {
printf("%lld ", b[i]);
}
return 0;
}
不想用数组写,有人用 vector 过了吗?