集合幂级数
写在前面
-
大概就是看了一些题解总结了一下得出的东西
-
肯定有很多错误,欢迎指出
-
目前学习的不多,希望轻喷
问题引入
-
对于一个大小为 \(n\) 的异或为 \(0\) 的集合,有 \(2^n\) 种选择的方案使得选出两个集合的异或和为 \(0\)
-
对于每个元素的贡献都是 \(2\) ,那么其实我们就要求 FWT 意义下的 \([x^0]\prod (1+2x^{a_i})\)
-
一个想法就是对于每个元素都正变换,然后点值乘起来,然后再逆变换,但是复杂度太高了
-
考虑 FWT 正变换的意义是 \((-1)^{c(i\&j)}\) ,那么就可以发现正变换后每个数只会是 \(-1\) 或 \(3\)
-
那么我们考虑求出每一位有多少位是 \(-1\) ,多少位是 \(3\)
-
我们可以考虑将每一位加起来然后用一元一次方程来解出每一位 \(-1\) 的个数,剩下的个数就是 \(3\) 了
-
而 \(FWT(A)+FWT(B)=FWT(A+B)\) ,所以我们将 \(FWT(\sum 1+2x^{a_i})\) 正变换后,求出每一位 \(-1\) 和 \(3\) 的个数,然后算出乘积,最后逆变换回来,但是就是 \([x^0]IFWT\)
进阶问题
-
显然答案就是 \(\prod(Xx^{a_i}+Yx^{b_i}+Zx^{c_i})\) FWT 变换后的每一项的系数
-
还是考虑按照上面的做法,但是这样每一位的数字就会有 8 种可能性,太麻烦了
-
考虑利用异或的自反性,我们将每一组的每个数字都异或上 \(a_i\) ,最终的结果异或上 $\bigoplus_{i=1}^n a_i $ 就是原答案了
-
那么现在的三元组就是 \((0,b_i\bigoplus a_i,c_i\bigoplus a_i)\) ,下面的 \(b,c\) 以新的三元组为标准
-
那么实际上就是求 \(\prod (X+Yx^{b_i}+Zx^{c_i})\)
-
那么现在的可能就只有 4 种了,考虑仍然像上面那样用方程来解
-
设 \(X-Y-Z=d_1,X-Y+Z=d_2,X+Y-Z=d_3,X+Y+Z=d_4\)
-
注意到我接下来所谈到的 \(d\) 都是关于 FWT 数组的某一项的相关数量
-
第一个方程: \(d_1+d_2+d_3+d_4=n\)
-
其实可以发现这里的 \(d_1,d_2,d_3,d_4\) 和 \(X,Y,Z\) 是没有关系的,只和 \(a_i,b_i,c_i\) 有关系
-
我们让 \(X,Y,Z\) 取特殊值来设出接下来的 3 个方程
-
当 \(X=0,Z=0,Y=1\) 的时候,每一项的贡献只和 \(Y\) 有关
-
第二个方程: \(d_3+d_4-d_1-d_2=[x^i]FWT\)
-
当 \(X=0,Y=0,Z=1\) 的时候,每一项的贡献只和 \(Z\) 有关
-
第三个方程: \(d_2+d_4-d_1-d_3=[x^i]FWT\)
-
最后一个方程,我们考虑 \(Y,Z\) 同时做贡献,也就是令 \(x^{b_i\bigoplus c_i}\) 的系数为 1 ,其余的为 0
-
对于每一位的系数实际上就是 \(\sum_i (-1)^{j\&(b_i\bigoplus c_i)}=\sum_i (-1)^{j\& b_i}(-1)^{j\&c_i}\)
-
第四个方程: \(d_1-d_2-d_3+d_4=[x^i]FWT\)
-
然后就解这四个方程就可以知道对于每一位所有值分别的个数了,然后还原成原本的值,再 IFWT 回去就得到了答案数组,输出答案的时候记得 \(\bigoplus_{i=1}^n a_i\)
问题模型
- 然而通过特殊的处理处理了上面的类似问题还不够,考虑这个问题的模型
求形如 $\prod_{i=1}^n \sum_{j=0}^{len-1} w_jx^{a_{i,j}} $ FWT 变换后的每一项的系数,假设 \(a_{i,j}\leq 2^{k}\)
- 最暴力的肯定就是 \(O(n2^kk)\) ,瓶颈在于 \(O(n2^k)\),考虑能不能像上面一样解方程
想法一
-
一共有 \(2^{len}\) 种取值,假设出现次数为 \(v_0,v_1,...,v_{2^{len}-1}\) ,对于一位如果为 \(1\) ,说明此处的实际取值为 \(-1\)
-
我们此时理论上需要 \(2^{len}\) 个方程,第一种就是和为 \(n\) ,所以还需要 \(2^{len}-1\)
-
仍然考虑取特殊值
-
我们考虑枚举每一个子集的贡献,去掉一个都不选的情况,刚好就会有 \(2^{len}-1\) 个方程出现
-
设取的子集的二进制表示为 \(T\),假设为集合 \(S\) ,那么对于每一项的系数就是 \(\sum_i (-1)^{j\&{a_{i,S_1}}}(-1)^{j\&{a_{i,S_2}}}...(-1)^{j\& a_{i,S_n}}\)
-
那么考虑当前方程的每一个 \(v_i\) 的系数就是 \((-1)^{T\&i}\)
-
方程设好后直接暴力解
-
那么理论复杂度就是 \(O(2^{len}2^kk+2^k2^{3len}+2^kk)\)
-
复杂度的瓶颈在于解方程的 \(O(n^3)\) 上
想法二
-
当我们枚举一个子集 \(T\) ,特殊值取 \(1\) 的时候,在方程种 \(v_i\) 的系数就是 \((-1)^{T\& i}\)
-
实际上这是 FWT 系数,现在我们考虑将每一位单独看,下面所讨论都是针对于每一位
-
我们考虑将数组 \(v\) FWT 后,每一项 \(T\) 就是 \(\sum_{i} (-1)^{i\& T} v_i\) ,可以发现这个东西就是关于集合 T 的方程,假设这个数组为 \(H\) ,那么我们只要将 \(H\) 逆变换回去就是 \(v\) 数组了
-
对于一个子集关于一项方程的答案是很好求的,我们记录下每个子集关于每一项的答案
-
然后对于每一项逆变换回去就可以得到这一项的 \(v\) 了
-
理论复杂度就是 \(O(2^{len}2^kk+2^k2^{len}len+2^kk)\)
-
这里就不再是暴力的解方程,而是利用了一个很巧妙的性质