edu119 G (高维前缀和 + 容斥原理)
G. Subsequences Galore
一道高维前缀和的典题,转化过程涉及到容斥原理。
核心在于:对于一个字符串集合(用二进制数 \(x\) 表示状态),直接求 “至少是该集合中的某一个字符串的子序列的不同字符串数量”(设为 \(G(x)\)) 是不容易的,但是求 “是该集合内所有字符串的子序列的不同字符串数量”(设为 \(H(x)\)) 非常简单:只要对于任何一种字母,字符串中该字母的数量不超过字符串集合中所有字符串该字符数量的最小值,设对于第 \(i\) 种字母为 \(c_{i}\),则答案为:
\[\prod_{i=1}^{26} (1+c_{i})
\]
题目需要求的是给定字符串集合的所有子集的 \(G(x)\) 之和再经过一个很复杂的转换后的结果。考虑分别计算每个字符串集合子集的 \(G(x)\) 值,我们可以通过容斥原理将 \(H(x)\) 转化到 \(G(x)\),进而求解。
有:
\[G(x) = \sum_{S\subseteq x,S\neq \emptyset}(-1)^{|S|}*H(S),S表示二进制状态
\]
如果直接按照上面的式子计算每个子集的 \(G(x)\),时间复杂度显然无法接受。可以利用 SOSdp 优化这一过程:先将 \((-1)^{|S|}\) 这一部分归到 \(H(S)\) 内(即集合的二进制状态表示中含有奇数个 \(1\) 为正,偶数个 \(1\) 为负),转化后变为:
\[G(x) = \sum_{S\subseteq x}H(S),S表示二进制状态
\]
此时 \(G(x)\) 就等价于 \(x\) 的所有子集的 \(H(S)\) 之和,这个就是高维前缀和的板子,具体实现:
for(int c = 0; c < n; c ++){
for(int state = 0; state < (1<<n); state ++){
if(state >> c & 1){
H[state] = (H[state] + H[state ^ (1<<c)]) % mod;
}
}
}
!!!注意必须要先枚举二进制位,再枚举状态。

浙公网安备 33010602011771号