集合幂级数学习笔记
定义集合幂级数 \(F(x)=\sum_{S}f_Sx^S\),\(S\) 是集合。单位元 \(\epsilon =x^{\varnothing}\)。
集合幂级数的卷积
FMT / FWT 我们很熟知,其实是作用在集合幂级数上的快速变换。
对于一个集合运算(位运算)\(\otimes\),设变换 \(\hat F_S=\sum_{T}g(S, T)F_T\)。满足
我们可以发现 \(g(S,i\otimes j)=g(S,i)g(S,j)\),可以据此构造各种变换。
集合并卷积
也叫二进制数下的或卷积。
若 \(H=F\times G\),
现在 \(g(S,i\cup j)=g(S,i)g(S,j)\),构造变换 \(\hat F\):
即子集和,可以通过 FWT 解决,对二进制数按位考虑。也可看作高维前缀和。
IFWT 就是差分回去。
inline void FWT_or(int *f, int n, int op) {
for (int mid = 1; mid < n; mid <<= 1)
for (int i = 0; i < n; i += mid << 1)
for (int j = 0; j < mid; ++j) {
if (op == 1) f[i + mid + j] += f[i + j];
else f[i + mid + j] += P - f[i + j];
f[i + mid + j] %= P;
}
}
集合交卷积(与卷积)同理,\(\hat F_S=\sum_{T\supseteq S}F_T\)。
对称差卷积
也叫二进制数下的异或卷积。定义两个集合的对称差运算为 \(A\oplus B=\{x|[x\in A]\operatorname{xor}[x\in B]\}\),即二进制数的异或操作。
若 \(H=F\times G\),
现在 \(g(S,i\oplus j)=g(S,i)g(S,j)\),构造变换 \(\hat F\):
通过 FWT 解决。
inline void FWT_xor(int *f, int n, int op) {
for (int mid = 1; mid < n; mid <<= 1)
for (int i = 0; i < n; i += mid << 1)
for (int j = 0; j < mid; ++j) {
int x = f[i + j], y = f[i + mid + j];
f[i + j] = (x + y) % P;
f[i + mid + j] = (x - y + P) % P;
if (op == -1) {
f[i + j] = 1ll * f[i + j] * inv2 % P;
f[i + mid + j] = 1ll * f[i + mid + j] * inv2 % P;
}
}
}
子集卷积
若 \(H=F\times G\),
在满足 \(i\cup j=S\) 的情况下,\(i\cap j=\varnothing\) 可以转化为 \(|i|+|j|=|S|\)。
于是我们将集合幂级数 \(\sum_SF_Sx^S\) 的 \(F_S\) 替换为占位多项式 \(F_S(z)=f_Sz^{|S|}\)。然后做集合并卷积,最后只要保留 \([z^{|S|}]F_S(z)\)。这样做其实是增加一维来去掉不合法的贡献。
由于一般情况下多项式的次数很低,使用 \(\mathcal O(n^2)\) 的多项式乘法更为合适。
集合幂级数的进阶运算
若无说明,此节中集合幂级数的卷积为子集卷积,集合幂级数的变换为 FMT。
集合幂级数很多运算其实就是变换后的多项式运算。已经不知道自己是在学集合幂级数还是形式幂级数了。
求逆
把变换后的 \(\hat F\) 各项的多项式 \(f_S(z)\) 求逆,再逆变换回来就是 \(F^{-1}\)。
多项式的 \(\mathcal O(n^2)\) 求逆:
\[\begin{aligned} \sum_{i=0}^{n}f_if^{-1}_{n-i}&=[n=0]\\ \sum_{i=1}^{n}f_if^{-1}_{n-i}+f_0f^{-1}_n&=[n=0]\\ \end{aligned} \]那么可以递推,当 \(n=0\) 时 \(f^{-1}_0=\frac{1}{f_0}\),其他情况
\[f^{-1}_n=-\frac{1}{f_0}\bigg(\sum_{i=1}^{n}f_if^{-1}_{n-i}-1\bigg) \]
ln & exp
定义
,要求 \([x^\varnothing]F(x)=0\)。注意 \(F(x)^k\) 是 \(F(x)\) 的 \(k\) 次幂,而这里 \(F(x)*F(x)\) 为子集卷积。
定义
,要求 \([x^\varnothing]F(x)=1\)。
当然求 \(\exp,\ln\) 是没法按定义式算的,应该和求逆一样,FWT 后对每个占位多项式做 \(\mathcal O(n^2)\) 的暴力 \(\exp,\ln\)。
多项式 \(\mathcal O(n^2)\) \(\exp\) 和 \(\ln\):
\[e^{F(x)}=G(x) \]对 \(x\) 求导
\[\begin{aligned} \frac{\operatorname d e^{F(x)}}{\operatorname dx}&=\frac{G(x)}{\operatorname dx}\\ \frac{\operatorname dF(x)}{\operatorname dx}\frac{\operatorname de^{F(x)}}{F(x)}&=G'(x)\\ F'(x)e^{F(x)}&=G'(x)\\ F'(x)G(x)&=G'(x)\\ \end{aligned} \]拆开并得到递推式
\[(n+1)g_{n+1}=\sum_{i=0}^n(i+1)f_{i+1}g_{n-i} \]\[g_n=\frac 1 n \sum_{i=1}^{n}if_{i}g_{n-i} \],就可以递推求得 \(\exp(F(x))\) 了。
这个式子同样可以得到 \(\ln(F(x))\) 的递推式,拆出一项 \(f_{n+1}\),
\[\sum_{i=1}^{n-1}(i+1)f_{i+1}g_{n-i}+(n+1)f_{n+1}g_0=(n+1)g_{n+1} \]得到
\[(n+1)f_{n+1}=(n+1)g_{n+1}-\sum_{i=0}^{n-1}(i+1)f_{i+1}g_{n-i} \]\[f_n=g_n-\frac 1 n\sum_{i=1}^{n-1}if_{i}g_{n-i} \],就可以递推求得 \(\ln(F(x))\) 了。
导数
定义
所以一个集合幂级数的导数为
分治卷积
留坑。
应用
参考资料
- 位运算卷积(FWT) & 集合幂级数 - command_block
- 集合幂级数学习笔记 - RainAir
- 真正理解快速沃尔什变换/快速莫比乌斯变换(FWT|FMT) - Rockdu
- 集合幂级数学习笔记 - Sshwy
- 子集卷积及其高级运算 - Great_Influence

浙公网安备 33010602011771号