1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| #include <bits/stdc++.h> using namespace std;
const int G = 3; const int maxn = 2e5 + 5; const int mod = 998244353;
int R[maxn];
int qpow(int a, int b) { int res = 1; for (; b; b >>= 1, a = 1LL * a * a % mod) if (b & 1) res = 1LL * res * a % mod; return res; }
void NTT(int limit, int *A, int type) { for (int i = 0; i < limit; i++) if (i < R[i]) swap(A[i], A[R[i]]); for (int mid = 1; mid < limit; mid <<= 1) { int wn = qpow(G, (mod - 1) / (mid << 1)); for (int pos = 0; pos < limit; pos += (mid << 1)) { int w = 1; for (int k = 0; k < mid; k++, w = 1LL * w * wn % mod) { int x = A[pos + k], y = 1LL * w * A[pos + mid + k] % mod; A[pos + k] = (x + y) % mod; A[pos + k + mid] = (x - y + mod) % mod; } } } if (type == 1) return; for (int i = 1; i < limit / 2; i++) swap(A[i], A[limit - i]); int inv = qpow(limit, mod - 2); for (int i = 0; i < limit; i++) { A[i] = 1LL * A[i] * inv % mod; } }
void mulNTT(int *f, int *g, int *h, int n, int m) { int limit = 1, L = 0; while (limit <= n + m) limit <<= 1, L++;
for (int i = n + 1; i < limit; ++i) f[i] = 0; for (int i = m + 1; i < limit; ++i) g[i] = 0;
for (int i = 0; i < limit; ++i) R[i] = (R[i >> 1] >> 1) | ((i & 1) << (L - 1));
NTT(limit, f, 1), NTT(limit, g, 1); for (int i = 0; i < limit; ++i) h[i] = 1LL * f[i] * g[i] % mod; NTT(limit, h, -1); }
int a[maxn], f[maxn], g[maxn], h[maxn]; int inv[maxn], fact[maxn], infact[maxn];
void init() { inv[0] = inv[1] = 1; for (int i = 2; i < maxn; i++) inv[i] = 1LL * (mod - mod / i) * inv[mod % i] % mod; fact[0] = infact[0] = 1; for (int i = 1; i < maxn; i++) { fact[i] = 1LL * fact[i - 1] * i % mod; infact[i] = 1LL * infact[i - 1] * inv[i] % mod; } }
vector<int> solve(int l, int r) { if (l == r) return {1, a[l]}; int mid = (l + r) >> 1; int len1 = mid - l + 1, len2 = r - mid; auto res1 = solve(l, mid); auto res2 = solve(mid + 1, r); for (int i = 0; i <= len1; i++) f[i] = res1[i]; for (int i = 0; i <= len2; i++) g[i] = res2[i]; mulNTT(f, g, h, len1, len2);
vector<int> res; res.resize(len1 + len2 + 1); for (int i = 0; i <= len1 + len2; i++) res[i] = h[i]; return res; }
void Main() { int n; cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; auto res = solve(1, n); int ans = 0; for (int i = 1; i <= n; i++) { ans += 1LL * res[i] * fact[i] % mod * fact[n - i] % mod; if (ans >= mod) ans -= mod; } ans = 1LL * ans * infact[n] % mod; cout << ans << '\n'; }
int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
init(); int T; cin >> T; while (T--) Main(); return 0; }
|