集合幂级数

基本概念

定义

  • \(2^{X}\) 表示 \(X\) 的所有子集组成的集合。注意,此时元素是集合

本质就是全集的各个子集到值域的映射。

形式化地来说就是,域 \(F\) 上的集合幂级数是 \(2^U\to F\) 的函数,对于每个 \(S\subseteq U\),都有 \(f_s \in F\)

从多项式的角度理解,就是把之前的下标为某个数字改为为某个具体集合。

表示

我们用 \(cx^s\) 表示 \(f_s=c\),于是集合幂级数就可以表示为 \(f=\sum\limits_{S\in U}f_sx^s\)

加法与乘法

加法直接对应系数相加即可,注意此时 \(f\)\(g\) 必须全集相同。

乘法 \(h=f\times g=(\sum\limits_{L\in 2^U}f_Lx^L)\times(\sum\limits_{R\in 2^U}g_Rx^R)\)。当集合幂级数的乘法对加法有分配律的时候有,

\[h=f\times g=\sum\limits_{L\in 2^U}\sum\limits_{R\in 2^U}f_Lx^L\times g_Rx^R \]

我们设 \(f_Lx^L\times g_Rx^R=(f_L\times g_R)x^{L*R}\),其中 \(\times\) 就是 \(F\) 域乘法,\(*\) 就是集合域运算,且满足结合律和交换律

根据 \(*\) 的不同有不同算法,以下一一介绍。

集合并卷积 / OR 卷积

就是把上述 \(*\) 定义为 \(\bigcup\),然后我们就可以得到 $$h_s=\sum\limits_{L\in 2^U}\sum\limits_{R\in 2^U}[L\cup R=S]f_Lg_R$$
暴力计算时间复杂度 \(O(4^n)\)

莫比乌斯变换(FMT)

定义快速莫比乌斯变换,\(f'={\rm FMT}(f)\),为 \(f'_i=\sum\limits_{j\subset i}f_j\),也就是子集求和。

定义快速莫比乌斯反演,\(f'={\rm FMI}(f)\),为 \(f'_i=\sum\limits_{j|i=i}(-1)^{|i|-|j|}f_j\)

其中 FMT 和 FMI 互为逆变换。对于 OR 卷积,我们只需要把 \(f\)\(g\) 做一下 FMT,然后 \(h_i\gets f_i\times g_i\),最后对于 \(h\) 做一个 FMI 就解决了。

莫比乌斯变换可以通过高维前缀和来实现,所以我们对于 FMT 就是做一个系数为 \(1\) 的高维前缀和,对于 FMI 就是做一个系数为 \(-1\) 的高维前缀和。

莫比乌斯变换的本质是容斥原理,原先 \(L\cup R=S\) 这个限制条件使得我们难以拆开 \(f\)\(g\),因为二者互相关联。考虑使用容斥原理,我们钦定 \(S\) 中为 \(0\) 的位置,在 \(L\cup R\) 的结果中也为 \(0\)。于是我们就把限制宽松到了两个子集,只需要满足 \(L\subset S\)\(R\subset S\) 即可,这就可以通过做一次高维前缀和(FMT),然后对应位置相乘就行了。你钦定完之后,还需要设计容斥系数(FMI),系数是 \((-1)^{(n-|L|)-(n-|S|)}=(-1)^{|S|-|L|}\)

沃尔什变换(FWT)

对于卷积 \(h\gets f\times g\),我们按照二进制最高位的奇偶性分为 \(f_0,f_1,g_0,g_1,h_0,h_1\)

\[h_0=f_0\times g_0 \]

\[h_1=f_1\times g_0+f_0\times g_1+f_1\times g_1=(f_0+f_1)(g_0+g_1)-f_0g_0 \]

发现以上都可以通过 \((f_0+f_1)\times (g_0+g_1)\)\(f_0\times g_0\) 求解出来。

进行如下变换,

\[\begin{matrix} &f_0 &f_1 &g_0 &g_1\\ &\Downarrow &\Downarrow &\Downarrow &\Downarrow \\ &f_0 &f_0+f_1 &g_0 &g_0+g_1 \end{matrix}\]

变换之后,递归求 \(I_0=f'_0\times g'_0\)\(I_1=f'_1\times g'_1\) 即可。递归到底层的时候就是对应位置直接乘就行了。回溯的时候进行如下变换,

\[\begin{matrix} &h_0 &h_1\\ &\Uparrow &\Uparrow \\ &I_0 &I_1-I_0 \end{matrix}\]

很容易写出一个分治的形式,但是常数很大,我们将其改成非递归形式。

容易发现其实往下递归的时候是 \(f_0\) 不变,\(f_1\gets f_0+f_1\),往上回溯的时候也是 \(f_0\) 不变,\(f_1\gets f_1-f_0\)。我们可以将这两部分的代码,传入一个系数 \(t=1\) 或者 \(t=mod-1\)

为了模拟递归,我们先要枚举递归层数,也就是正在处理的这一位 \(2^k\),然后分开枚举 \(>2^k\)\(<2^k\) 的值就行了。拼在一起就是当前正在做的数字。

for(int k=1;k<full;k<<=1)
    for(int i=0;i<full;i+=(k<<1))
        for(int j=0;j<k;j++) 
            add(f[i|j|k],1ll*f[i|j]*t%mod);

集合交卷积 / AND 卷积

就是把上述 \(*\) 定义为 \(\bigcap\),然后我们就可以得到 $$h_s=\sum\limits_{L\in 2^U}\sum\limits_{R\in 2^U}[L\cap R=S]f_Lg_R$$

不管是理解还是推导方面,都和 OR 卷积是一样的,就不过多赘述了。

莫比乌斯变换(FMT)

把 OR 卷积中系数为 \(+1\)\(-1\) 的高维前缀和,改为系数为 \(+1\)\(-1\) 的高维后缀和即可。

容斥的时候钦定 \(L\cap R\) 中为 \(1\) 的位置是 \(S\) 即可。

沃尔什变换(FWT)

也是几乎和 OR 卷积一模一样。

先进行 FWT,

\[\begin{matrix} &f_0 &f_1 &g_0 &g_1\\ &\Downarrow &\Downarrow &\Downarrow &\Downarrow \\ &f_0+f_1 &f_1 &g_0+g_1 &g_0 \end{matrix}\]

再进行 IFWT,

\[\begin{matrix} &h_0 &h_1\\ &\Uparrow &\Uparrow \\ &I_0-I_1 &I_1 \end{matrix}\]

集合对称差卷积 / XOR 卷积

就是把上述 \(*\) 定义为 \(\bigoplus\),然后我们就可以得到

\[h_s=\sum\limits_{L\in 2^U}\sum\limits_{R\in 2^U}[L\bigoplus R=S]f_Lg_R \]

暴力计算时间复杂度 \(O(4^n)\)。关于 XOR 卷积就没有 FMT 了,只能进行 FWT。

沃尔什变换(FWT)

定义沃尔什变换 \(f'={\rm FWT(f)}\),为 \(f'_s=\sum\limits_{T\in 2^U}f_T(-1)^{\lvert S\cap T\rvert}\)
定义沃尔什逆变换,\(f'={\rm IFWT(f)}\),为 \(f'_s=\dfrac{1}{2^n}\sum\limits_{T\in 2^U}f_T(-1)^{\lvert S\cap T\rvert}\)

对于卷积 \(h\gets f\times g\),我们按照二进制最高位的奇偶性分为 \(f_0,f_1,g_0,g_1,h_0,h_1\)

\[h_0=f_1\times g_1+f_0\times g_0 \]

\[h_1=f_1\times g_0+f_0\times g_1 \]

发现以上都可以通过 \((f_0+f_1)\times (g_0+g_1)\)\((f_0-f_1)\times (g_0-g_1)\) 组合出来。

进行如下变换,

\[\begin{matrix} &f_0 &f_1 &g_0 &g_1\\ &\Downarrow &\Downarrow &\Downarrow &\Downarrow \\ &f_0+f_1 &f_0-f_1 &g_0+g_1 &g_0-g_1 \end{matrix}\]

变换之后,递归求 \(I_0=f'_0\times g'_0\)\(I_1=f'_1\times g'_1\) 即可。递归到底层的时候就是对应位置直接乘就行了。回溯的时候进行如下变换,

\[\begin{matrix} &h_0 &h_1\\ &\Uparrow &\Uparrow \\ &\dfrac{I_0+I_1}{2} &\dfrac{I_0-I_1}{2} \end{matrix}\]

将上面这个递归形式改成非递归形式就行了。\(\dfrac{1}{2}\) 提取出来放到最后乘,每一位都要乘以 \(\dfrac{1}{2}\),所以总计是乘以 \(\dfrac{1}{2^n}\)

void FWT(int *f,bool type){
	for(int k=1;k<full;k<<=1)
		for(int i=0;i<full;i+=(k<<1))
			for(int j=0;j<k;j++){
				int x=f[i|j],y=f[i|j|k];
				f[i|j]=(x+y)%mod; f[i|j|k]=(x-y+mod)%mod;
			}
	if(!type) return ;
	for(int i=0;i<full;i++) f[i]=1ll*f[i]*invp%mod;
}

线性代数角度的 FWT

我们设 \(f'_s=\sum\limits_{T\in 2^U}c_{s,t}f_T\)

由于变换后对应位置相乘需要满足 \(*\) 运算,所以 \(c_{i,j*k}=c_{i,j}c_{i,k}\)。还是和之前拆位思想相同。我们对于每一位独立进行上述变化。此时只需要考虑 \(s,t\) 的某一个二进制位,所以下标取值只有 \(0/1\),故这是一个 \(2\times 2\) 的矩阵。

按位或矩阵

\[\begin{bmatrix}1&0\\ 1&1 \end{bmatrix} \]

其逆矩阵为

\[\begin{bmatrix}1&0\\ -1&1\end{bmatrix} \]

按位与矩阵

\[\begin{bmatrix}1&1\\0&1\end{bmatrix} \]

其逆矩阵为

\[\begin{bmatrix}1&-1\\0&1\end{bmatrix} \]

按位异或矩阵

\[\begin{bmatrix}1&1\\0&-1\end{bmatrix} \]

其逆矩阵为(为了减少常数,可以把 \(\frac{1}{2}\) 提取出来,最后再乘)

\[\begin{bmatrix}0.5&0.5\\0.5&-0.5\end{bmatrix} \]

其实很好理解,根据之前的推导,OR 卷积和 AND 卷积的变换应该是要求一个是对于子集求和,一个是对于超集求和。或矩阵中的 \(10,01,11\to 1\)\(00\to 0\) 恰好对应子集求和的形式。与矩阵同理。异或矩阵也符合我们推到的 FWT 的系数。

从这个角度,我们可以看出 FWT 是一种线性变换。

子集卷积 集合幂级数 exp/ln/求逆

前置知识,\(n^2\) 多项式操作

子集卷积

要求就是不相交集合的并。也就是要求 \(L\bigcup R=S\)\(\lvert L\rvert+\lvert R\rvert=\lvert S\rvert\)

exp

组合意义:将大集划分为无序小集合的方案数,也就是

\[G_S=\sum\limits_{\cup s_i=S,\sum |s_i|=|S|}\prod a_{s_i} \]

ln

组合意义:把元素组合成集合的方案数。

求逆

\[G(x)=\dfrac{1}{F(x)} \]

做法

我们对于每种大小的集合幂级数进行 FMT/FWT,然后关于大小那一个维度进行 \(O(n^2)\) 多项式各种操作,最后再 FMI/IFWT 回去。由于 \(n\) 很小,所以暴力多项式操作的时间复杂度是正确的。

最后 \(h_s\) 取大小为 \(\operatorname{popcount}(s)\) 集合幂级数中的 \(s\) 即可。

这样子就是有 \(n\) 种集合幂级数进行变换。时间复杂度 \(O(n^22^n)\)

题目

五道模板题:FMT/FWT子集卷积expln求逆

P13275 [NOI2025] 集合

存在使用集合幂级数硬推的做法,但是本题解从更容易入手的容斥原理来做。

这种很多限制导致难以计算的题目很容易去想容斥,问题来了?我们该对 $P\cap Q=\emptyset $ 容斥,还是对于 \(f(P)=f(Q)\) 容斥。都试一试,发现对于前者是 \(2^{2^n}\) 的,没有前途。所以考虑后者,你直接对于 \(f(P)=f(Q)\) 这个东西想叶也很难直接做,比如说你钦定什么,对具体哪个东西容斥?

再来一步枚举,这个题就变得就清晰了。我们枚举 \(S\),考虑 \(f(P)=S,f(Q)=S\) 这种情况的答案,如果 \(f(P)\) 恰好等于 \(S\) 是难做的,故考虑容斥,枚举 \(U\),钦定 \(f(P)\) 的结果中 \(U\) 中的 \(1\) 必须出现,系数是 \((-1)^{|U|-|S|}\)。对于 \(f(Q)\) 的限制,也是同理枚举 \(V\)。所以二元组 \((U,V)\) 对于 \(S\) 的容斥系数就是 \((-1)^{|U|+|V|-2|S|}=(-1)^{|U|+|V|}\)。接下来要考虑贡献,由于是钦定,我们只需要对于 \(V\subset i\) 或者 \(U\subset i\)\(i\) 进行决定是否选择,对于只是 \(U,V\) 中的一个的超集的 \(i\),其方案数是 \(a_i+1\),对于同时是 \(U,V\) 超集的 \(i\),其方案数是 \(2a_i+1\)(要么不选,要么先选 \(U\) 还是 \(V\),再选 \(a_i\) 种方案)。

暴力枚举 \((U,V)\)\(S\)\(O(8^n)\) 的,由于 \(S\)\(U\cap V\) 的子集,有一个想法是算出 \((U,V)\) 的方案和系数,贡献到 \(U\cap V\) 这个集合上,然后再做一次高维后缀和对于每一个 \(S\) 都统计出贡献。但是这么做很唐,因为我们并不需要求出每个 \(S\) 的答案,只需要求出总的答案,满足条件的 \(S\)\(2^{|U \cap V|}\) 种,直接计数就行了。

所以对于 \((U,V)\) 对于答案的贡献是 \(2^{|U \cap V|}(-1)^{|U|+|V|}\prod\limits_{U\subset i,V\nsubseteq i}(a_i+1)\prod\limits_{U\nsubseteq i,V\subset i}(a_i+1)\prod\limits_{U\subset i,V\subset i}(2a_i+1)\)

为了快速计算后面的那一坨乘积式,我们设 \(f_s=\prod\limits_{s\subset i}a_i\)\(g_s=\prod\limits_{s\subset i}\dfrac{2a_i+1}{(a_i+1)^2}\)。那么 \((U,V)\) 的权值为 \(f_Uf_Vg_{U\cup V}\)。同时改写系数 \(2^{|U\cap V|}=2^{|U|+|V|-|U\cup V|}\),就可以将下标全部转化为 \(U\)\(V\)\(U\cup V\) 了,这个时候使用 or-FWT,就可以把 \(U,V\) 的贡献放到 \(U\cup V\) 处进行统计了。

但是有一个问题,就是我们 \(g\) 的分母为 \(a_i+1=0\) 的时候怎么办?考虑扩域,我们对于每个数字记录 \((v,k)\) 代表其权值为 \(v\times 0^k\)。乘法的时候直接是 \(0\) 的个数相加。加法的时候,显然只有 \(k\) 小那个会产生贡献,如果相等就都加。减法的时候,\((v_1,k_1)-(v_2,k_2)\),一定有 \(k_1\le k_2\),当 \(k_1<k_2\) 的时候无贡献,否则就是 \(v_1-v_2\)

这题就成功解决了,时间复杂度 \(O(n2^n)\)

三进制 MEX 卷积

定义三进制 \(\operatorname{mex}\) 运算,先将两个数字 \(a,b\) 进行三进制拆分,形如 \(a=\sum a_i3^i\)\(\operatorname{mex}(a,b)=\sum\limits_{i=0}^{k-1}\operatorname{mex}(a_i,b_i)\)。也就是说把每个数都拆成三进制表示,然后对于每个三进制位进行 \(\operatorname{mex}\)
定义三进制 \(\operatorname{mex}\) 卷积为

\[h_s=\sum\limits_{\operatorname{mex}(L,R)=S}f_L\times g_S \]

给定长度为 \(3^{n}\)\(f\)\(g\),求解 \(h\)\(n\le 10\)

还是按照 FWT 那套方法,对于当前的最高位的值进行分类。

\[c_0=a_1b_1+a_1b_2+a_2b_1+a_2b_2=(a_1+a_2)(b_1+b_2) \]

\[c_1=a_0b_0+a_0b_2+a_2b_0=(a_0+a_2)(b_0+b_2)-a_2b_2 \]

\[c_2=(a_0+a_1+a_2)(b_0+b_1+b_2)-c_0-c_1 \]

发现我们需要构造四种乘法,

\[(a_0,a_1,a_2)\to (a_1+a_2,a_0+a_2,a_2+a_0+a_1+a_2) \]

这样子递归是 \(3^n\to 4^n\),因为三项变四项。

逆变换,令上述分别为 \(A,B,C,D\)\((A,B,C,D)\to (A,B-C,D-A-B-C)\)

可以递归计算,时间复杂度是 \(O(n4^n)\)

QOJ5089. 环覆盖

给定一张 \(n\) 个点,\(m\) 条边的简单无向图,对每个 \(i\in [0,m]\),计算它只保留 \(i\) 条边,使得剩下的图是一个可环覆盖图的方案数。可环覆盖的定义是,可以将边集划分成若干个子集,使得每个子集都形成一个环。

UVA13277 XOR Path

我咋想到点分治上面去了。

注意到异或是可以抵消的,而本题恰好是边权,所以有 \(w(x,y)=w(1,x)\oplus w(1,y)\),这样子就和 \(\rm LCA\) 无关了,求出每个点到根的异或和,然后直接做一个 xor-FWT 统计答案就做完了。

AGC034F RNG and XOR

FWT 版本的高斯消元。

posted @ 2024-07-28 11:51  Mirasycle  阅读(201)  评论(0)    收藏  举报