集合幂级数

集合幂级数

(我写下这行的时候还不知道集合幂级数是啥,但这并不影响我们慢慢学)

首先,FFT FWT 之类的,都可以看作对原序列进行线性变化,然后对应位置相乘,再逆变换回来得到答案。那我们可以把序列看成向量,把变换看成矩阵。这是一种理解方式,这样,这些操作的线性性是显然的。

我们直接推导一下异或 FWT 的表达形式。

\[FWT(A)_k=\sum_{i=0}^na_{ki}A_i\\ \begin{aligned} &FWT(A)_kFWT(B)_k=FWT(A\oplus B)_k\\ \iff& \sum_{i=0}^na_{ki}A_i\sum_{i=0}^nb_{ki}B_i=\sum_{i=0}^na_{ki}\sum_{j\oplus w=k} A_jB_w\\ \iff& \sum_{i=0}^n\sum_{j=0}^na_{k,i}a_{k,j}A_iB_j=\sum_{i=0}^n\sum_{j=0}^na_{k,i\oplus j}A_iB_j\\ \iff& a_{k,i}a_{k,j}=a_{k,i\oplus j} \end{aligned} \]

通常,取

\[A=\begin{bmatrix} 1&1\\ 1&-1 \end{bmatrix} A^{-1}=\begin{bmatrix} \frac{1}{2}&\frac{1}{2}\\ \frac{1}{2}&-\frac{1}{2} \end{bmatrix} \]

你可以把这个当成多元 FFT。我们平常做的 FFT 其实就是长度是 \(2^k\) 的不进位加法,也就是循环卷积。

然后我们对于有很多位的,考虑定义 \(F_{x,y}=\prod_{i=0}^{\log n} A_{x_iy_i}\),那么由每位独立的性质,我们可以得到:

\[\begin{aligned} F_{x,y}F_{x,z}&=\prod_{i=0}^{\log n}A_{x_iy_i}A_{x_iz_i}\\ &=\prod_{i=0}^{\log n}A_{x_iy_i\oplus z_i}\\ &=F_{x,y\oplus z} \end{aligned} \]

事实上,\(FWT(A)_k=\sum_{i=0}^{2^n-1}a_{ki}A_i=\sum_{i=0}^{2^n-1}(-1)^{\text{popcount}(i\cap k)}A_i\)

事实上,我们这个 F 在做 Kronecker 积,如果我们记 \(\oplus\) 为 Kronecker 积,乘法是矩阵乘法,那么有性质。

\[(A\oplus B)(C\oplus D)=(AC\oplus BD) \]

其中 \(A,B,C,D\) 都是方阵。

然后,利用这个,我们有

\[A\oplus B\oplus C=(A\oplus I_n\oplus I_n)(I_n\oplus B\oplus I_n)(I_n\oplus I_n\oplus C) \]

因为我们事实上要算 \(F(A\oplus \dots \oplus A)\),其中 \(F\) 是向量,\(A\) 是原矩阵。那么我们知道可以拆成矩阵乘法,然后拆出来的矩阵是稀疏的,最多有 \(n^{k+1}\) 个非零项,所以复杂度是 \(O(k2^{k+1})\)

子集卷积

你也可以叫它集合不交并卷积。形式化来讲:

\[h_k=\sum\limits_{i\cap j=0 \ i\cup j=k}f_ig_j \]

我们来先随便胡一个做法。你考虑容斥 \(i\cap j=0\) 这个限制,然后变成有一个集合,要求这里面每一位都是 1,然后还要求 \(i\cup j=k\)。如果你枚举的是 \(S\),那么后面这部分我们可以做到 \(2^{n-|S|}(n-|S|)\),清算复杂度。

\[\sum_{S}2^{n-|S|}(n-|S|)=\sum_{i=0}^n\binom{n}{i}i2^i=2n3^{n-1} \]

复杂度 \(O(n3^n)\),这个稍微有点逊。

我们换一个视角。构造 \(F_k=\sum_{i=0}^{2^n-1}[|i|=k]f_ix^i\)\(G_k\) 同理。这个叫占位多项式。

之前那个条件等价于 \(i\cup j=k,|i|+|j|=|k|\)。这样,我们实质上是要前面做或卷积后面做和卷积。事实上这可以直接用 Kronecker 积构造对应的矩阵,这样复杂度是 \(O(n(2^nn)+n^22^n)=O(n^22^n)\),事实上我们后面说的做法完全就是在实现这一过程。

我们计算 \(F_i\times G_j\to H_{i+j}\),其中乘法是或卷积。然后对每个 \(H_k\) 只保留 \(|i|=k\) 的项,就行了。

这个东西拓展到三个卷起来可以做到 \(n^32^n\),但是多了就不行了。多了的话,我们可能需要真的对和这一维做 FFT。

然后就是要求这么一个式子

\[dp_S=\sum_{T\subset S}dp_Tg_{S-T} \]

我们可以考虑按 \(|S|\) 从小往大做,有人(spx)叫它半半在线卷积。还有全半在线卷积,不懂。

\(n^2\) 多项式操作

如果我们构造 \(F(x)=\sum a_ix^i\),其中,定义多项式的乘法是上述各类卷积。那么,我们可以对这个多项式进行一些 ln/exp/inv 之类的操作。

你比方说我们还是构造占位多项式。\(F_0\dots F_n\),我们把这 \(n+1\) 个多项式当成另外一个多项式 \(F'\) 的系数。\(G'F'=1,G'=\frac{1}{1-F'}\)。对比系数,可以得到

\[G_i=-\frac{1}{F_0}\sum_{j=0}^iF_{n-j}G_j \]

其中 \(G_i\) 也是多项式。然后我们定义多项式之间的乘法是或卷积,实现的时候可以先 FMT 最后再统一 IFMT,然后就可以了。

这东西原理我还是不是很清楚,但是我们可以先写几个式子。

\[\exp(F)=G\iff G'(x)=F'(x)G(x)\\ \ln(F)=G\iff \frac{F'(x)}{F(x)}=G'(x) \]

比较系数即可。

但是,这个东西,好像也没啥用。本来都可以用子集卷积的形式来表示出来。

还是,没太看懂。

reference

集合幂级数 蔡欣然

https://codeforces.com/blog/entry/96003

posted @ 2024-01-24 17:05  PYD1  阅读(10)  评论(0)    收藏  举报