CF2030E MEXimize the Score 题解
题面
假设我们将数组 \(b\) 中的元素分割成任意多个 \(k\) 的非空多集 \(S_1, S_2, \ldots, S_k\) ,其中 \(k\) 是一个任意的正整数。定义 \(b\) 的分值为任意整数 \(k\) 的 \(\operatorname{MEX}(S_1)\) \(^{\text{∗}}\) $ + \operatorname{MEX}(S_2) + \ldots + \operatorname{MEX}(S _ k)$ 在 \(b\) 的所有可能分区中的最大值。
给 Envy 一个大小为 \(n\) 的数组 \(a\) 。由于他知道计算 \(a\) 的得分对你来说太容易了,所以他要求你计算 \(a\).\(^{\text{†}}\) 的所有 \(2^n - 1\)$$ 非空子序列的得分之和。由于这个答案可能很大,请输出它对 \(998,244,353\) 取模的结果。
整数集合 \(c_1, c_2, \ldots, c_k\) 中的 \(^{\text{∗}}\) \(\operatorname{MEX}\) 定义为在集合 \(c\) 中不出现的最小非负整数 \(x\) 。例如, \(\operatorname{MEX}([0,1,2,2]) = 3\) 和 \(\operatorname{MEX}([1,2,2]) = 0\) 。
\(^{\text{†}}\) 如果 \(x\) 可以通过删除几个(可能是零个或全部)元素从 \(y\) 得到,那么序列 \(x\) 就是序列 \(y\) 的子序列。
题解
记 \(cnt_i\) 表示数字 \(i\) 在可重集合中出现的次数,对于单个集合,我们很容易知道一个最完美的划分可以达到的分数是 \(cnt_0 + \min(cnt_0+cnt_1) + \ldots + \min(cnt_0+cnt_1+\ldots+cnt_{n-1})\),贪心的考虑把相同的数字分到不同的集合,必定可以构成 \(0\) 到 \(t\) 的一个排列,此时的 \(\operatorname{MEX}\) 和可以达到最大,接下来我们考虑如何求出所有子集的价值和。
不妨设有这样一个集合,这个集合的价值可以通过构造一个 \(0, 1, ..., t\) 排列得到,排列存在当且仅当:
\]
因此我们考虑分成的子集排列分别能得到的价值,可以发现,这个排列中的每一个元素恰好贡献 \(1\),求每个排列中元素的价值总和转换成求每个元素对所有排列的总贡献。
假定最开始所有的集合并为空集,我们逐个插入元素,使得所有集合的并恰好不重复的是 \(S\) 的一个子集。
记 \(f(t) = \sum\limits_{i = k}^{cnt_t}\binom{cnt_t}{i}\),容易发现 \(f(t)\) 相当于把 \(t\) 元素插入 \(i\) 个不同的集合中,相当于把这些元素先插入 \(k\) 个 \(0 \sim t - 1\) 的排列中,这部分元素有 \(1\) 的贡献,剩余的 \(i - k\) 个元素也插入集合中,但是此部分元素没有直接贡献,仅仅可以让集合并变成一个新的子集 ,剩余的 \(r\) 个元素也可以组成 \(2^r\) 个集合,这些集合插入进去也不会影响现有的答案的贡献,因为我们仅仅计算的是元素 \(t\) 产生的贡献,他们可以任意插入已有的排列中,并且不改变 \(t\) 存在的价值。
我们不妨枚举 \(k\),对于每个 \(k\),我们考虑尽可能长的构建 \(k\) 个 \(0 \sim t\) 排列,容易知道最大的 \(t\) 满足 \(\min(cnt_0, cnt_1, \ldots, cnt_{t}) \ge k\),同样,对于每个 \(t\) 我们也需要去计算他的答案。
对 \(0\) 元素来说,拿出 \(k\) 个元素作为合法集合,共有 \(\binom{cnt_0}{k}\) 种不同集合并形式,再考虑将多余的 \(0\) 任意插入进去,这部分的贡献是 \(f(0)\),对于除了 \(0\) 以外的剩余 \(r\) 个元素,可以任意放入集合并且不影响答案,根据乘法原理,贡献是所有操作的种类数的积,此部分的 \(0\) 的答案与并出来的子集数量一致,直接加到答案上即可。
到 \(t\) 元素时,同样,对于前 \(t - 1\) 的元素已经考虑插入完成,有 \(\prod\limits_{i = 0}^{t - 1}f(i)\) 种子集,此时插入方式有 \(f(t)\) 种,对于其后的元素同样考虑是否加入,也有 \(2^r\) 种方式,至此,我们的答案就可以通过上述方案递推求出。
发现 \(\sum\limits_{i = 0}^{n - 1}cnt_{i} = n\),因此时间复杂度为 \(O(n)\),不会超时。
参考代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10, mod = 998244353;
int n, a[N], suf[N], pow2[N], frac[N], inv[N];
ll ksm(ll a, ll k)
{
ll res = 1;
while (k)
{
if (k & 1) res = res * a % mod;
k >>= 1;
a = a * a % mod;
}
return res;
}
void init()
{
pow2[0] = frac[0] = 1;
for (ll i = 1; i < N; i ++ ) pow2[i] = 2ll * pow2[i - 1] % mod, frac[i] = frac[i - 1] * i % mod;
inv[N - 1] = ksm(frac[N - 1], mod - 2);
for (ll i = N - 1; i; i -- ) inv[i - 1] = inv[i] * i % mod;
}
int binom(int a, int b)
{
return 1ll * inv[b] * inv[a - b] % mod * frac[a] % mod;
}
void solve()
{
cin >> n;
vector<int> cnt(n);
for (int i = 1; i <= n; i ++ ) cin >> a[i], cnt[a[i]] ++ ;
suf[n - 1] = 1;
for (int i = n - 1; i; i -- ) suf[i - 1] = 1ll * suf[i] * pow2[cnt[i]] % mod;
ll ans = 0, p = 0;
vector<int> f(n), g(n);
g = cnt;
for (int k = n; k; k -- )
{
while (p < n && cnt[p] >= k) p ++ ;
ll res = 1;
for (int i = 0; i < p; i ++ )
{
while (g[i] >= k) (f[i] += binom(cnt[i], g[i])) %= mod, g[i] -- ;
res = res * f[i] % mod;
(ans += res * suf[i] % mod) %= mod;
}
}
cout << ans << endl;
}
int main()
{
init();
int T;
cin >> T;
while (T -- ) solve();
return 0;
}
CF2030E MEXimize the Score 题解的更多相关文章
- C++版 - UVa1585 Score - 题解
C++版 - UVa1585 Score - 题解 <算法竞赛入门经典(第二版)> 习题3-1 得分(ACM/ICPC Seoul 2005,UVa1585) 问题描述: 给出一个由O和X ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- ZOJ 3819 Average Score(平均分)
Description 题目描述 Bob is a freshman in Marjar University. He is clever and diligent. However, he is n ...
- 洛谷P2722 总分 Score Inflation
P2722 总分 Score Inflation 184通过 295提交 题目提供者该用户不存在 标签USACO 难度普及- 提交 讨论 题解 最新讨论 关于算法 题目背景 学生在我们USACO的 ...
- UVA 12906 Maximum Score 排列组合
Maximum Score Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/vie ...
- hdu 5268 ZYB loves Score 水题
ZYB loves Score Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 【2013南京区域赛】部分题解 hdu4802—4812
上周末打了一场训练赛,题目是13年南京区域赛的 这场题目有好几个本来应该是我擅长的,但是可能是太久没做比赛了各种小错误代码写的也丑各种warusn trush搞得人很不爽 全场题之一的1002也没有想 ...
- HDU1789(Doing Homework again)题解
HDU1789(Doing Homework again)题解 以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定任务分数和其截止日期,每日可完成一任务,输出当罚分尽可能小时 ...
- Score(规律)
Score Time Limit : 5000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submiss ...
随机推荐
- 题解:SP22382 ETFD - Euler Totient Function Depth
题目链接: link,点击这里喵. 前置知识: [模板]线性筛素数,欧拉函数,点击这里喵. 题意简述: 给定整数 $l,r,k$,求出 $[l,r]$ 中有多少个整数不断对自己取欧拉函数刚好 $k$ ...
- 使用 nuxi build-module 命令构建 Nuxt 模块
title: 使用 nuxi build-module 命令构建 Nuxt 模块 date: 2024/8/31 updated: 2024/8/31 author: cmdragon excerpt ...
- 阿里云 ACK Pod重启:pod was OOM killed
原因为:limits和requests的值设定为一样的了, pod request达到了limit限制,kubelet会统计到request+缓存就超限,然后触发自动重启 resources: lim ...
- android 访问域名接口报错
1. 移动端访问https域名及接口,显示 java.net.UnknownHostException: Unable to resolve host "xxx" : No add ...
- C语言指针进阶
目录 字符指针 指针数组 数组指针 数组指针的定义 &数组名VS数组名 数组指针的使用 数组参数.指针参数 一维数组传参 二维数组传参 一级指针传参 二级指针传参 一级指针 二级指针 数组指针 ...
- Playwright 源码 BrowserType
playwright-java 的 Browser.BrowserContext.Page 挺好理解的,唯独这厮,就有一丢丢 -- package com.microsoft.playwright; ...
- C#整合Ollama实现本地LLMs调用
前言 近两年AIGC发展的非常迅速,从刚开始的只有ChatGPT到现在的很百家争鸣.从开始的大参数模型,再到后来的小参数模型,从一开始单一的文本模型到现在的多模态模型等等.随着一起进步的不仅仅是模型的 ...
- ASP.NET Core – Upload and Download Files (上传和下载文件)
前言 以前得文章 Asp.net core 学习笔记 ( upload/download files 文件上传与下载 ), 这篇是修订版. Handle Upload File (处理上传文件) 我的 ...
- DOM & BOM – Input File, Drag & Drop File, File Reader, Blob, ArrayBuffer, File, UTF-8 Encode/Decode, Download File
前言 之前写过 2 篇关于读写文件和二进制相关的文章 Bit, Byte, ASCII, Unicode, UTF, Base64 和 ASP.NET Core – Byte, Stream, Dir ...
- MDC – Work with Framework & Customize
前言 在 MDC – Material Design, Angular Material, MDC, MWC, Lit 的关系 中, 我有提到基于 MDC 的 Framework 生态有多糟糕. 但它 ...