集合幂级数
集合幂级数
(我写下这行的时候还不知道集合幂级数是啥,但这并不影响我们慢慢学)
首先,FFT FWT 之类的,都可以看作对原序列进行线性变化,然后对应位置相乘,再逆变换回来得到答案。那我们可以把序列看成向量,把变换看成矩阵。这是一种理解方式,这样,这些操作的线性性是显然的。
我们直接推导一下异或 FWT 的表达形式。
通常,取
你可以把这个当成多元 FFT。我们平常做的 FFT 其实就是长度是 \(2^k\) 的不进位加法,也就是循环卷积。
然后我们对于有很多位的,考虑定义 \(F_{x,y}=\prod_{i=0}^{\log n} A_{x_iy_i}\),那么由每位独立的性质,我们可以得到:
事实上,\(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,B,C,D\) 都是方阵。
然后,利用这个,我们有
因为我们事实上要算 \(F(A\oplus \dots \oplus A)\),其中 \(F\) 是向量,\(A\) 是原矩阵。那么我们知道可以拆成矩阵乘法,然后拆出来的矩阵是稀疏的,最多有 \(n^{k+1}\) 个非零项,所以复杂度是 \(O(k2^{k+1})\)。
子集卷积
你也可以叫它集合不交并卷积。形式化来讲:
我们来先随便胡一个做法。你考虑容斥 \(i\cap j=0\) 这个限制,然后变成有一个集合,要求这里面每一位都是 1,然后还要求 \(i\cup j=k\)。如果你枚举的是 \(S\),那么后面这部分我们可以做到 \(2^{n-|S|}(n-|S|)\),清算复杂度。
复杂度 \(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。
然后就是要求这么一个式子
我们可以考虑按 \(|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\) 也是多项式。然后我们定义多项式之间的乘法是或卷积,实现的时候可以先 FMT 最后再统一 IFMT,然后就可以了。
这东西原理我还是不是很清楚,但是我们可以先写几个式子。
比较系数即可。
但是,这个东西,好像也没啥用。本来都可以用子集卷积的形式来表示出来。
还是,没太看懂。
reference
集合幂级数 蔡欣然

浙公网安备 33010602011771号