CF2030E 简记

CF2030E

题目描述

假设我们将数组 \(b\) 的元素划分为任意数量 \(k\) 个非空多重集 \(S_1, S_2, \ldots, S_k\),其中 \(k\) 是任意正整数。定义 \(b\) 的得分为所有可能划分下 \(\operatorname{MEX}(S_1) + \operatorname{MEX}(S_2) + \ldots + \operatorname{MEX}(S_k)\) 的最大值。

给你一个长度为 \(n\) 的数组 \(a\)。由于他知道你计算 \(a\) 的得分太容易了,因此他要求你计算 \(a\) 的所有 \(2^n - 1\) 个非空子序列的得分之和。由于答案可能很大,请你输出其对 \(998\,244\,353\) 取模的结果。

做法:

先考虑一个集合怎么划分才能使得 \(\operatorname{MEX}\) 的和最大。

假设:各个数字的数量如下:

\(0\) \(1\) \(2\) \(3\) \(4\)
\(3\) \(4\) \(1\) \(2\) \(2\)

那么,能产生贡献的最优划分如下:

\([0,1,2,3,4,5]\)

\([0,1,2]\)

\([0,1]\)

所以,一个集合能划分出的 \(MEX\) 的最大和就是:

\[\sum_{i=0} \min_{j\le i}C_j \]

其中 \(C_i\) 表示数 \(i\) 出现的次数。

这一步并不难发现。

但关键是题目需要求出所有子序列的权值和。

考虑子序列的几种做题方法:

  1. 贡献法

  2. 极值类:枚举最大值最小值是谁

  3. 按位拆贡献

  4. \(DP\) :处理增量

  5. ...

此处增量和贡献是不好求的,这是因为与答案有关的是某一种数的个数,而并非某一个数的贡献。

所以有一个大概的思路就是:

按照数的大小顺序处理,由于答案与前缀最小出现次数有关,所以设 \(dp[i][j]\) 表示前 \(i\) 个数,最小出现次数是 \(j\) 的子序列个数。

转移大致如下:

设 \(S(c,j)=\sum_{k=j}^{n}\binom{c}{j}\) ,即这种颜色至少选了 \(j\) 个的方案数。

\[dp[i][j]=dp[i-1][j]\times S(cnt[i],j)+\sum_{k>j}^{n}dp[i-1][k]\times \binom{cnt[i]}{j} \]

注意 \(j\) 只枚举到 \(\min (cnt[i],mn)\) 。\(mn\) 表示前缀最小出现次数。

当前前缀产生的贡献:

设 \(precnt=\sum_{j=0}^{i}cnt[j]\) ,则:

\[\sum_{j\ge 1} j\times dp[i][j]\times 2^{n-precnt} \]

原因是最小出现次数为 \(j\) 则每个子序列在这一轮对答案产生 \(j\) 的贡献(对应的是 \(\min_{j\le i}C_j\) )。

而这样子序列的个数是 \(dp[i][j]\times 2^{n-precnt}\) ,原因是后面的数字可以随便选。

由于 \(j\) 最多只会枚举到 \(cnt[i]\) ,所以整体是 \(O(n)\) 的。

用滚动数组优化后可以做到空间时间都是:

\[O(n) \]

posted @ 2026-10-22 11:29  wlhao  阅读(5)  评论(0)    收藏  举报