ABC215G
首先先把颜色都离散化。
设 \(f\) 为所求答案,那么对于 \(f(1)\sim f(n)\) 分别计算其期望。因为期望的线性性,分别考虑每种颜色被选中至少一个的概率(因为每种颜色对答案的贡献是 \(1\) 所以期望就等于概率)。
设有 \(m\) 种不同颜色,第 \(i\) 种颜色出现次数为 \(cnt_i\),则有:
\[f(k)=\sum_{i=1}^{m}\dfrac{\dbinom{n}{k}-\dbinom{n-cnt_i}{k}}{\dbinom{n}{k}}
\]
显然过不去,但是发现对于出现次数一样的颜色,它们的贡献也一样。
于是设 \(g(i)\) 表示出现次数为 \(i\) 的颜色个数。那么原式变成:
\[f(k)=\sum_{i=1}^{n}g(i)\dfrac{\dbinom{n}{k}-\dbinom{n-i}{k}}{\dbinom{n}{k}}
\]
经典结论,\(g(i)\ne0\) 的个数是 \(\mathcal O(\sqrt n)\) 的。
于是总复杂度 \(\mathcal O(n\sqrt n)\)。
Code:
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
typedef long long ll;
typedef pair <int, int> pii;
const int N = 50005, mod = 998244353;
int n;
int a[N], b[N], cnt;
int fac[N], inv[N];
int sum[N], num[N];
vector <pii> vec;
int qpow(int x, int y) {
int res = 1;
while (y) {
if (y & 1) res = 1ll * res * x % mod;
x = 1ll * x * x % mod;
y >>= 1;
}
return res;
}
void init(int maxn) {
fac[0] = 1;
for (int i = 1; i <= maxn; ++i) fac[i] = 1ll * fac[i - 1] * i % mod;
inv[maxn] = qpow(fac[maxn], mod - 2);
for (int i = maxn - 1; ~i; --i) inv[i] = 1ll * inv[i + 1] * (i + 1) % mod;
}
int C(int n, int m) {
if (n < 0 || m < 0 || n < m) return 0;
return 1ll * fac[n] * inv[n - m] % mod * inv[m] % mod;
}
void add(int &a, int b) {
a += b;
if (a >= mod) a -= mod;
}
int main() {
scanf("%d", &n); init(n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
b[++cnt] = a[i];
}
sort(b + 1, b + cnt + 1); cnt = unique(b + 1, b + cnt + 1) - (b + 1);
for (int i = 1; i <= n; ++i) a[i] = lower_bound(b + 1, b + cnt + 1, a[i]) - b, ++sum[a[i]];
for (int i = 1; i <= cnt; ++i) ++num[sum[i]];
for (int i = 1; i <= n; ++i) if (num[i]) vec.pb(pii(i, num[i]));
for (int k = 1; k <= n; ++k) {
int ans = 0;
for (auto tmp : vec) add(ans, 1ll * tmp.se * ((C(n, k) - C(n - tmp.fi, k) + mod) % mod) % mod);
ans = 1ll * ans * qpow(C(n, k), mod - 2) % mod;
printf("%d\n", ans);
}
return 0;
}