基本操作
集合并卷积
集合幂卷积定义为:给定两个集合幂级数 \(F,G\),计算集合幂级数 \(H\) 满足:
\[\begin{aligned} h_S=\sum_{L\subset 2^U}\sum_{R\subset 2^U}[L\cup R=S]f_Lg_R \end{aligned} \]
我们考虑用类似于 FFT 的方式,把 \(f,g\) 按某种线性变换后,然后把问题变成点乘。
由于位运算按位独立,我们可以把 \(F,G\) 拆成:
\[F=F^-+x^{\{n\}}F^+,G=G^-+x^{\{n\}}G^+ \]所以我们得到:
\[H=F^-\cdot G^-+x^{\{n\}}((F^-+F^+)\cdot (G^-+G^+)-F^-\cdot G^-) \]这样我们就把问题用 \(O(2^n)\) 的代价变成了两个 \(2^{n-1}\) 项的集合幂级数的并卷积,时间复杂度为 \(T(n)=2T(n-1)+O(2^n)=O(n2^n)\)。
由于这个我们涉及到递归和数组复制,导致常数不理想,我们可以考虑像 FFT 一样,将这个过程变成非递归的。
我们发现,每一次我们就是将 \(2^{n-1}\le i<2^n\) 的 \(f_i\) 加上 \(f_{i-2^{n-1}}\) 即可。
然后我们从小到大枚举 \(i\),然后进行加操作即可。
这一部分被我们称为 FMT,我们设 FMT 之后的数组为 \({\hat f}_S,{\hat g}_S,\hat h_S\)。
我们考虑怎么变回去,手玩之后知道一个 \(T\subset S\),\(\hat h_T\) 对于 \(h_S\) 的容斥系数是 \((-1)^{|S|-|T|}\),这个你随便证一下就好了。
我们发现,这是一个线性变换,所以我们是可以构造矩阵描述这个过程的,真是好涩,具体可以看 cmd 先生的博客
虽然矩阵很好理解,但是由于没有学过另一种描述导致你可能会在 ZJOI2019 开关里面看不懂 solution,所以可能还是要学会一下这个神秘的东西。
然后交卷积和并本质相同。
集合对称差卷积
集合幂卷积定义为:给定两个集合幂级数 \(F,G\),计算集合幂级数 \(H\) 满足:
\[\begin{aligned} h_S=\sum_{L\subset 2^U}\sum_{R\subset 2^U}[L\oplus R=S]f_Lg_R \end{aligned} \]
我们还是考虑把 \(x^{\{n\}}\) 提出来分治,则我们知道:
\[FG=(F^-\cdot G^-+F^+\cdot G^+)+x^{\{n\}}(F^-\cdot G^++F^+\cdot G^-) \]如果直接算,你发现还是 \(O(4^n)\) 的,我们考虑构造 \(A=(F^-+F^+)(G^-+G^+),B=(F^--F^+)(G^--G^+)\),则
\[H=\frac {p+q}2+x^{\{n\}}\frac {p-q}2 \]时间复杂度 \(O(n2^n)\)。
沃尔什变换
还是考虑集合对称差卷积,我们进行一步转化:
\[[S=\varnothing]=\frac 1 {2^n}\sum_{T}(-1)^{|S\cap T|} \]证明:
- \(S=\varnothing\),显然成立
- 否则我们任意从 \(S\) 选出一个 \(x\),包含 \(x\) 和不包含 \(x\) 的 \(T\) 一一对应且和正好为 \(0\),证毕。
注意到 \(L\oplus R=S\) 等价于 \(L\oplus R\oplus S=0\),且 \((L\oplus R)\cap S=(L\cap S)\oplus (R\cap S)\),所以;
\[\begin{aligned} h_S&=\sum_{L\subset 2^U}\sum_{R\subset 2^U}[L\oplus R=S]f_Lg_R\\ &=\frac1 {2^n}\sum_{T\subset 2^n}\sum_{L\subset 2^U}\sum_{R\subset 2^U}(-1)^{|(L\oplus R\oplus S)\cap T|}f_Lg_R\\ &=\frac1 {2^n}\sum_{T\subset 2^n}(-1)^{|S\cap T|}(\sum_{L\subset 2^U}(-1)^{|L\cap T|}f_L)(\sum_{R\subset 2^U}(-1)^{|R\cap T|}g_R)\\ \end{aligned} \]所以我们令 \(\hat f_S=\sum_{T}f_T(-1)^{|S\cap T|}\) 即可,它被成为 \(f\) 的 沃尔什变换,也记作 \(\text{FWT}(f)\)。
同理,我们定义 \(\hat f_S\) 的 沃尔什逆变换 为 \(f_S=\frac1 {2^n}\sum_T\hat f_T(-1)^{|S\cap T|}\),也记作 \(\text{IFWT}(\hat f)\)。
考虑证明这两个互逆:
\[\begin{aligned} f_S&=\frac 1 {2^n}\sum_T\hat f_T(-1)^{|S\cap T|}\\ &=\frac1 {2^n}\sum_T\sum_Xf_X(-1)^{|(S \oplus X)\cap T|}\\ &=\sum_X f_X\frac 1 {2^n}\sum_T(-1)^{|(S \oplus X)\cap T|}\\ &=\sum_Xf_X[S\oplus X=0]=f_S \end{aligned} \]然后我们考虑怎么计算 沃尔什(逆)变换。
设我们枚举到了 \(j\) 位,对于 \(p=i\) 和 \(q=i+2^{j-1}\),我们发现沃尔什变换就是让 \(f'(p)=f(p)+f(q),f'(q)=f(p)-f(q)\),而逆变换则在最后乘上 \(\frac 1 {2^n}\) 即可。
子集卷积
定义集合之间的卷积为不交集合并,即
\[h_S=\sum_L\sum_R[L\cup R=S][L\cap R =\varnothing]f_Lg_R \]暴力可以做到 \(O(3^n)\) 但是不够优秀。
我们发现,当 \(L\cup R=S\) 时,\(L\cap R=\varnothing\) 的充要条件是 \(|L|+|R|=|S|\),所以我们转二元 GF,然后把 \(F_{|L|,L}\) 和 \(G_{|R|,R}\) 贡献到 \(H_{|L|+|R|,L\cup R}\),那么 \(h_S=H_{|S|,S}\),然后你可以对于 \(F_{1\sim n},G_{1\sim n}\) 做 \(\text{FWT}\),然后暴力卷积一下,最后对 \(H_{1\sim n}\) \(\text{IFWT}\) 回来即可,时间复杂度 \(O(n^22^n)\)。
集合幂级数求逆
我们先对行 FWT,然后列多项式求逆,然后列 IFWT 回来即可。
集合幂级数 exp
我们先对行 FWT,然后列 exp,然后列 IFWT 回来即可,对列 exp 可以使用 \(O(n^2)\) 多项式。
然后组合意义和形式幂级数的相似: 选取若干个不相交的集合组合成S的方案数。
集合幂级数 ln
我们先对行 FWT,然后列 ln,然后列 IFWT 回来即可,对列 ln 可以使用 \(O(n^2)\)
然后由 exp 的组合意义可以得到 ln 的组合意义: 将S拆分成若干个不相交集合的方案数
习题
[ABC212H] Nim Counting
根据 Nim 游戏,我们知道先手必胜是 xor 和不为 \(0\)。
则我们设 \(f(x)=\sum x^{A_i}\),所以我们需要知道:
\[\sum_{w>0}[x^w]\sum_{i=1}^Nf^i(x) \]由于 FWT 是线性变换,所以我们可以 FWT 之后做等比数列求和然后 IFWT 回来即可。
[WC2018] 州区划分
我们可以先简单的判断一个州是否是合法的,你直接判是否存在欧拉回路即可。
然后考虑集合幂级数,每次枚举最后加入的州的集合,然后类子集卷积地半在线卷积一下,就是按集合大小从小往大做就行了。
[NOI Online #3 提高组] 优秀子序列
我们令每个元素对应的生成函数是 \(x^\varnothing+x^{a_i}\),然后我们就要把所有的乘起来。
我们考虑付公主的背包,我们使用 ln+exp 来做。
我们推一下式子:
\[\begin{aligned} P(x)&=\prod_{i=1}^n(x^\varnothing +x^{a_i})\\ &=\exp\sum_{i=1}^n\ln(x^\varnothing+x^{a_i})\\ &=\exp \sum_{i=1}^n\sum_{k=1}\frac {(-1)^{k+1}(x^{a_i})^k}{k} \end{aligned} \]由于我们的乘积定义为子集卷积,所以上述式子只在 \(k=1\) 时有值,所以我们得到:
\[P(x)=\exp\sum_{i=1}^nx^{a_i} \]然后变成了 exp 板子,需要特判 \(a_i=\varnothing\)。
[CEOI2019] Amusement Park
我们考虑对于一个有向无环图,我们可以将边全部翻转仍然满足条件,互反的一组边反转次数为 \(m\),所以我们只需要计算方案数乘上 \(\frac m 2\) 即可。
然后我们考虑设 \(S\) 点集无环的方案数,我们考虑拆 DAG,钦定入度为 \(0\) 的点集 \(t\),则 \(t\) 为独立集,方案数是 \(F_{S-t}\),由于我们是钦定,所以还需要容斥,可以得到:
\[F_S=\sum_{T\subset S}(-1)^{|T|-1}[t 为独立集]F_{S-T} \]然后我们设这个系数的生成函数为 \(G\),则 \(F=FG+1,F=\frac 1 {1-G}\) 集合幂级数求逆即可。
LOJ 154. 集合划分计数
我们发现,就是子集卷积的 \(\exp\) ,只不过最多只能有 \(k\) 项。
我们考虑写出答案的生成函数 \(G\),得到:
\[\begin{aligned} G&=\sum_{n=0}^k\frac {F^n}{n!}\\ G'&=F'(G-\frac {F^k}{k!}) \end{aligned} \]所以我们只需要计算出 \(F^k\) 然后就可以提取两端系数递推即可,问题转化成集合幂级数快速幂,对一维 FWT 对另外一维 \(O(n^2)\) 计算多项式快速幂即可。
[ZJOI2019] 开关
我们考虑用集合幂级数 \(\sum_Sf_Sx^S\) 表示从 \(0\) 到 \(S\) 状态的期望时间,\(G\) 是转移系数,且我们知道 \(\sum_{T}g_T=1\),则我们可以知道:
\[F=\sum_Tx^T+F\times G+c\times x^\varnothing \]后面那个 \(c\) 是由于状态转移对于 \(x^\varnothing\) 不成立而加的特判。
现在我们需要求 \([x^U]F(x)\),我们先考虑对原式子做 FWT,则我们知道:
\[\begin{aligned} \\ [x^U]{\hat F}&=[x^U]{\hat F}[x^U]{\hat G}+\sum_T(-1)^{|T\cap U|}+c\\ [x^U]\hat F(1-[x^U]\hat G(x))&=\sum_T(-1)^{|T\cap U|}+c\\ \end{aligned} \]当 \(U=\varnothing\) 时,\([x^U]\hat G=1\),所以 \(c=-2^n\)。
对于其他的 \(U\),\([x^U]\hat G<1\),可以得到 \([x^U]\hat F=\frac c{1-[x^U]\hat G}\)。
然后做 \(\text{IFWT}\),得到:
\[\begin{aligned} f_S&=\frac 1 {2^n}\sum_T(-1)^{|S\cap T|}[x^T]\hat F\\ &=\frac 1 {2^n}([x^\varnothing]\hat F-2^n\sum_{T\not=\varnothing}(-1)^{|S\cap T|}\frac 1 {1-[x^T]\hat G})\\ \end{aligned} \]然后由于
\[\begin{aligned} \frac1 {2^n}\sum_T\hat f_T&=f_\varnothing,f_\varnothing=0\\ \hat f_0&=-\sum_{T\not=\varnothing }\hat f_T\\ \hat f_0&=2^n\sum_{T\not= \varnothing}\frac {1}{1-[x^T]\hat G} \end{aligned} \]所以我们知道:
\[\begin{aligned} f_S&=\sum_{T\not=\varnothing}\frac 1 {1-[x^T]\hat G}-\sum_{T\not=\varnothing}(-1)^{|S\cap T|}\frac 1 {1-[x^T]\hat G}\\ &=\sum_{T\not=\varnothing}2\times [|S\cap T|\equiv 1\bmod 2]\frac 1 {1-[x^T]\hat G}\\ &=\sum_{T\not=\varnothing}2\times [|S\cap T|\equiv 1\bmod 2]\frac 1 {1-(1-2\sum_{i\in T}p_i)}\\ &=\sum_{T\not=\varnothing}[|S\cap T|\equiv 1\bmod 2]\frac1 {\sum_{i\in T}p_i} \end{aligned} \]dp 即可,时间复杂度 \(O(n\sum p)\)。
[AGC034F] RNG and XOR
跟上一个题差不多,快进到
\[\forall U\not=\varnothing,[x^U]\hat F=\frac {-2^n}{1-[x^U]\hat G} \]然后我们发现,对于这个 \([x^\varnothing ]\hat F\) 好像不是很好算的样子,难绷。
我们发现
\[\frac 1 {2^n}\sum_T[x^T]\hat F=[x^\varnothing]F \]然后 \([x^\varnothing]F=0\),所以我们就可以知道 \([x^\varnothing ]\hat F=\sum_{T\not=\varnothing}[x^T]\hat F\),然后就能计算出来了,最后 IFWT 即可。
时间复杂度 \(O(n2^n)\)。
可能还有一些习题,但是鸽了
标签:frac,sum,cap,笔记,幂级数,varnothing,集合,aligned,hat From: https://www.cnblogs.com/Nityacke/p/18173675