集合幂级数学习笔记

集合幂级数

定义与 FWT

类似于形式幂级数,
对于一个全集,我们定义集合幂级数 \(F(x)=\sum_{s\subset U}f_{s}x^{s}\)
我们可以用一个长为 \(|U|\) 的 2 进制数表示一个集合,集合的并、交、对称差分别对应二进制数的 \(\or,\and,\oplus\)

我们可以定义集合幂级数的并卷积、交卷积、对称差卷积:

\[c_{k}=\sum_{i\or j=k}a_ib_j\\c_k=\sum_{i\and j=k}a_ib_j\\c_k=\sum_{i\oplus j=k}a_ib_j \]

我们思考我们熟知的形式幂级数 \(\max,\min\) 以及循环卷积的快速做法,对需要卷积的两个序列的系数施以一个合适的线性变换,进行点积,再进行逆变换得到答案。(三种卷积的线性变换分别是前缀和,后缀和,DFT)

由于对于 \(\or,\and,\oplus\) 来说按位独立,我们考虑将一个 \(|U|\) 位 2 进制数看成 \(|U|\) 维向量,我们可以将原本的集合幂级数看成 \(|U|\) 元的形式幂级数:\(\sum_{x_1,x_2,\cdots,x_{|U|}}f_sx_1^{s_1}x_2^{s_2}\cdots x_{|U|}^{s_{|U|}}\)
那么集合幂级数的三种卷积就是对 \(|U|\) 元都做 \(\max,\min\) 以及循环卷积的结果。

我们可以得到 3 种 FWT 的线性变换:

并卷积:\(\hat f_i=\sum_{j\and i=j}f_j\)
交卷积:\(\hat f_i=\sum_{j\or i=j}f_j\)
异或卷积:\(\hat f_i=\sum_{j}(-1)^{popcnt(i\and j)}f_j\)

FWT 的应用

使用 FWT 可以高效的处理集合幂级数卷积,有一些经典的技巧值得注意。

例 1

考虑求解集合幂级数 \(\prod_{i=1}^n(1+x^{a_i})\)(异或卷积)。

我们可以直接考虑 \(1+x^{p}\) 这样的式子 FWT 后的形式,即 \(\hat f_i=1+(-1)^{popcnt(i\and p)}\)
那么 \(\hat f_i\) 只有两种取值:0 或 2。我们如果知道 \(n\) 个二项式 FWT 后的结果有多少个 0,2,那么这 \(n\) 个值乘起来后的结果也唾手可得,再进行一次 IFWT 即可得到答案。

我们考虑统计 \(\sum_{j=1}^n(-1)^{popcnt(i\and a_j)}\) 即可解得 0,2 的个数。使用 FWT 计算该式即可。

子集卷积

单纯的并、交、对称差卷积可能并不够用,存在一些特别的问题可以抽象成子集卷积的形式。
我们定义子集卷积:

\[c_k=\sum_{i\or j=k,i\and j=0}a_ib_j \]

考虑通过扩元转化成我们已知的卷积。

\(F(x,y)=\sum_{s}f_sx^{s}y^{|s|}\),定义 \(x\) 元做并卷积,\(y\) 做加法卷积,那么子集卷积出的形式幂级数取 \(C(x)=[y^{|s|}]F(x,y)\) 即可。
由于每一元独立,我们考虑先对 \(x\) 元做 FWT 变换,直接处理 \(y\) 元的加法卷积,最后对 \(x\) 元逆变换回来即可。
时间复杂度 \(O(2^nn^2)\)

子集卷积意义下的初等函数

对于 \(f_0=0\) 的集合幂级数,在子集卷积意义下可以定义 \(\exp\),我们将并卷积意义下的集合幂级数看成黑盒,由于其有乘法,乘常数,和普通加法卷积意义下形式幂级数一样考虑 \(\exp\) 就行了。

具体的,将子集卷积中间处理 \(y\) 元的加法卷积的部分,改成处理 \(\exp\) 的部分即可,\(\ln\) 同理,均可以做到 \(O(2^nn^2)\)

可以以一道例题理解其组合意义:给定一个无向图,求其每个子集的划分成若干独立集的方案数。
\(f_s\) 表示集合 \(s\) 是否为独立集,那么对其做子集卷积意义下的 \(\exp\) 运算得到的集合幂级数就是答案。

posted @ 2022-09-17 19:32  juju527  阅读(146)  评论(0编辑  收藏  举报