ABC215G
首先先把颜色都离散化。
设 f 为所求答案,那么对于 f(1)∼f(n) 分别计算其期望。因为期望的线性性,分别考虑每种颜色被选中至少一个的概率(因为每种颜色对答案的贡献是 1 所以期望就等于概率)。
设有 m 种不同颜色,第 i 种颜色出现次数为 cnti,则有:
f(k)=m∑i=1(nk)−(n−cntik)(nk)
显然过不去,但是发现对于出现次数一样的颜色,它们的贡献也一样。
于是设 g(i) 表示出现次数为 i 的颜色个数。那么原式变成:
f(k)=n∑i=1g(i)(nk)−(n−ik)(nk)
经典结论,g(i)≠0 的个数是 O(√n) 的。
于是总复杂度 O(n√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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话