Note - 高维前缀和

又被称为 SOS DP。

介绍 / Introduction

为了以后方便,我们定义 \(p^d\)\(d\) 维前缀和。特殊地,零维前缀和 \(p^0\) 等于原值。

在讲解高维前缀和前,我们先考虑一维前缀和。给定序列 \(a\),定义 \(p_x^1 = \sum_{i=1}^{x} a_i\),显然暴力求这个是 \(\mathrm O(n^2)\) 的。发现 \(p_x^1 = p_{x-1}^1 + p_x^0\)如果不会这个建议重学普及组内容

接着,我们考虑二维前缀和。我们定义 \(p_{x, y}^2 = \sum_{i=1}^{x} \sum_{j=1}^{y} a_{i, j}\),发现暴力求是 \(\mathrm O(n^4)\) 的。我们发现 \(p_{x, y}^2 = p_{x-1, y}^2 + \sum_{i=1}^{y} a_{x, i}\)。于是我们定义 \(p_{x, y}^1 = \sum_{i=1}^{y} a_{x, i}\),发现 \(p_{x, y}^2 = p_{x-1, y}^2 + p_{x, y}^1\)

于是推广这个过程,我们得到 \(d\) 为前缀和的一个通用求法:\(1\) 维开始,对每维求前缀和。或者说,对于每一维,都求一次前缀和

这个方法可以把复杂度从 \(\mathrm O(n^{2d})\) 降低到 \(\mathrm O(dn^d)\),十分好用。又由于维度过高时一般取 \(n = 2\),所以这个方法也可以把枚举子集的 \(\mathrm O(3^n)\) 降低到 \(\mathrm O(n2^n)\)

至于实现,相信你们会的。

注意 \(n = 2\) 的高维前缀和又被称为子集和,而高维后缀和被称为超集和

例题 / Examples

CF165E Compatible Numbers

这是一个板子。

先求出子集和,然后查询一个数按位取反的结果的子集和即可。

CF449D Jzzhu and Numbers

发现这个题并不好做。

发现按位与的本质是集合并,于是我们考虑超集和,定义 \(f_S\) 为存在子集 \(S\) 的集合数量。那么交集存在子集 \(S\) 的方案数量自然是 \(2^{f_S}-1\)

然而我们需要交集为 \(\varnothing\) 的方案数量。于是我们使用容斥,即可得到 \(\mathrm {ans} = \sum (-1)^{|S|} 2^{f_S}-1\)

于是做完了。

CF383E Vowels

两集合有交不太好做,于是考虑反命题,即补集是另一集合的子集。

然后发现无脑子集和就做完了。

CF772D Varying Kibibits

你发现了一大坨式子。

\[G(x)=x\cdot\left((\sum_{S\subseteq T,S\neq \varnothing,f(S)=x}(\sum_{y\in S}y)^2)\bmod (10^9+7)\right) \]

一坨东西加起来在模一下再乘一个 \(x\) 然后不取模看起来就没什么性质。于是我们考虑里面的这个东西。(以下不考虑取模)

\[G(x) \cdot x^{-1} = \sum_{S\subseteq T,S\neq \varnothing,f(S)=x}(\sum_{y\in S}y)^2 \]

首先发现 \(S \neq \varnothing\) 没啥大用。然后我们唯一的突破口在 \(f(S)\) 上。我们发现 \(f(S)\) 这个东西有点像集合交,于是我们参考一下 CF449D 的做法超集和一下然后高维差分一下。

问题在于如何超集和。

我们定义 \(T_d(X) = \sum_{S\subseteq X}(\sum_{y\in S}y)^d\)。考虑合并两个集合 \(A, B(A \cap B = \varnothing)\)

显然地,每一个 \(A \cup B\) 的子集都可以唯一拆分为 \(A\) 的一个自己和 \(B\) 的一个子集的并。以下定义 \(s(X)\) 为集合 \(X\) 的元素和。

然后发现:

\[\begin{aligned} T_d(A \cup B) &= \sum_{S\subseteq A \cup B}(s(S))^d \\ &= \sum_{U \subseteq A} \sum_{V \subseteq B} (s(U)+s(V))^d \\ &= \sum_{U \subseteq A} \sum_{V \subseteq B} \sum_{i=0}^d {d \choose i} s(U)^i s(V)^{d-i} \\ &= \sum_{i=0}^d {d \choose i} (\sum_{U \subseteq A} s(U)^i) (\sum_{V \subseteq B} s(V)^{d-i}) \\ &= \sum_{i=0}^d {d \choose i} T_i(U) T_{d-i}(V) \end{aligned} \]

又发现本题只需要维护 \(T_2\),于是我们维护 \(T_0, T_1, T_2\),然后超集和的时候做集合合并即可。

posted @ 2026-06-03 21:46  Hootime  阅读(9)  评论(0)    收藏  举报