# 【UNR #3】百鸽笼

### 题解

$$G_i(x) = \frac {x^i} {n^i i!}, S_i(x) = \sum_{j \leq i} G_j(x)$$，那么可以写出第 $$i$$ 列的 EGF：

$F_i(x) = \frac {G_{a_i - 1}(x)} {n} \prod_{j \neq i} \sum_{k \geq a_j} G_k(x)$

$\mathrm{ans}_i = \sum_{j \geq 0} j![x^j]F_i(x)$

$F_i = \frac {G_{a_i - 1}} {n} \prod_{j \neq i} (e^{\frac xn} - S_{a_j - 1})$

### 代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)

{
int data = 0, w = 1; char ch = getchar();
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
return data * w;
}

const int N(35), Mod(998244353);
inline int upd(const int &x) { return x + (x >> 31 & Mod); }
int fastpow(int x, int y)
{
int ans = 1;
for (; y; y >>= 1, x = 1ll * x * x % Mod)
if (y & 1) ans = 1ll * ans * x % Mod;
return ans;
}

int n, m, a[N], f[N][N * N], h[N][N * N], fac[N * N], inv[N * N], rev[N * N];
void Mul(int x)
{
static int g[N][N * N];
for (int i = 0; i <= n; i++) std::memset(g[i], 0, (m + 1) << 2);
for (int i = 0; i <= n; i++)
for (int j = 0; j <= m; j++)
{
if (i) g[i][j] = f[i - 1][j];
for (int k = 0; k < a[x] && k <= j; k++)
g[i][j] = upd(g[i][j] - 1ll * f[i][j - k] * rev[k] % Mod * inv[k] % Mod);
}
for (int i = 0; i <= n; i++) std::memcpy(f[i], g[i], (m + 1) << 2);
}

void Div(int x)
{
static int g[N][N * N];
for (int i = 0; i <= n; i++) std::memcpy(g[i], f[i], (m + 1) << 2);
for (int i = 0; i <= n; i++)
for (int j = 0; j <= m; j++)
{
if (i) g[i][j] = upd(g[i][j] - g[i - 1][j]);
for (int k = 1; k < a[x] && k <= j; k++)
g[i][j] = (g[i][j] + 1ll * g[i][j - k] * rev[k] % Mod * inv[k]) % Mod;
g[i][j] = upd(-g[i][j]);
}
for (int i = 0; i <= n; i++) std::memcpy(f[i], g[i], (m + 1) << 2);
}

void calc(int x)
{
for (int i = 0; i <= n; i++) std::memset(h[i], 0, (m + 1) << 2);
for (int i = 0; i <= n; i++)
for (int j = a[x] - 1; j <= m; j++)
h[i][j] = 1ll * f[i][j - a[x] + 1] * rev[a[x]] % Mod * inv[a[x] - 1] % Mod;
}

int main()
{
#ifndef ONLINE_JUDGE
file(cpp);
#endif
n = read(), f[0][0] = fac[0] = rev[0] = 1, rev[1] = fastpow(n, Mod - 2);
for (int i = 1; i <= n; i++) m += (a[i] = read());
for (int i = 1; i <= m; i++) fac[i] = 1ll * fac[i - 1] * i % Mod;
for (int i = 2; i <= m; i++) rev[i] = 1ll * rev[i - 1] * rev[1] % Mod;
inv[m] = fastpow(fac[m], Mod - 2);
for (int i = m; i; i--) inv[i - 1] = 1ll * inv[i] * i % Mod;
for (int i = 1; i <= n; i++) Mul(i);
for (int i = 1, ans; i <= n; i++)
{
Div(i), calc(i), ans = 0;
for (int j = 0; j < n; j++) for (int k = 0; k <= m; k++)
ans = (ans + 1ll * fastpow(1ll * n * fastpow(n - j, Mod - 2) % Mod, k + 1) * fac[k] % Mod * h[j][k]) % Mod;
printf("%d ", ans), Mul(i);
}
return 0;
}

posted @ 2021-02-16 19:57  xgzc  阅读(129)  评论(0编辑  收藏  举报