对一类异或和计数问题的探讨
对一类异或和计数问题的探讨
by AmanoKumiko
起因是 ABC288Ex,简短的题目让我从中受益很多。
该计数问题一共有三种模型。
分别是:
1.\(n\) 个数的序列,每个数在 \([0,m-1]\) 上,求异或和为 \(X\) 的方案数,设为 \(A_n\)。
2.\(n\) 个数的集合,每个数在 \([0,m-1]\) 上,求异或和为 \(X\) 的方案数,设为 \(B_n\)。
3.\(n\) 个数的多重集合,每个数在 \([0,m-1]\) 上,求异或和为 \(X\) 的方案数,设为 \(C_n\)。
模型三
模型三和模型二之间有明显的关系,因为只要对第二种卷上一个 \(\frac{1}{(1-x^2)^m}\) 就行了。
接下来转化为每个数至多出现一次,也就是模型二的问题。
模型二
我们知道,模型一显然是一个更加可做的问题,但是缺乏模型一和二之间的对应。
不妨先假设模型二是有序序列,最后只需除掉一个阶乘。
然后考虑在模型一上容斥。
具体来说,是集合划分容斥。
我们有恒等式:
证明也不难,因为这相当于枚举圆排列,反演一下就得证了。
现在只需强制让每个集合内的数相同,集合之间不用管。
显然只有奇数大小的集合会有贡献,而其正好就是模型一中的问题。
接下来有两条路。
第一种适用于求所有项。
设 \(w_{i,j}\) 表示大小为\(i\)的序列,\(j\) 种数出现了奇数次,\(m-j\) 种数出现了偶数次的方案数。
那么
也就是枚举最后一个位置上填了什么。
那么最后有
每项都求出来就是 \(O(n^2)\) 的。
第二种使用于求单项。
考虑拉格朗日反演。
对于奇数大小的集合,最后再考虑填什么数,所以其 EGF 就是 \(F(x)=\frac{1}{2}(\ln(1+x)-\ln(1-x))\)。
对于偶数大小的集合,显然每个集合都有 \(m\) 种填法,所以就是 \(G(x)=\exp(\frac{m}{2}\ln(1-x^2))=(1-x^2)^{\frac{m}{2}}\)。
然后有
\(F(x)\) 的复合逆容易求解,就是 \(\frac{e^{2x}-1}{e^{2x}+1}\)。
剩下的问题是 well-known 的,于是这一部分是 \(O(n\log n)\) 的。
模型一
接下来考虑最本源的模型一。
一个 naive 的想法是数位 dp,记录位数和顶到上界的数的个数。
单次就是 \(O(n^2\log m)\) 的。
显然可以有更优的做法。
枚举一个公共的 lcp,然后从当前位填 \(0\) 的数中选出一个,剩下的全部任意填。
可以发现,最后用选出的这个数一定能凑出 \(X\)。
于是就是要算
\(S\) 表示 \(m\) 剩余位组成的数。
稍微化简一下就可以变成幂和问题,于是就能做到单次 \(O(\log m)\)。
当 \(X=0\) 时:
令 \(k=popcount(m)\)。
求单项时,可以做到 \(O(k\log n)\)。
求前 \(n\) 项时,使用分治NTT就能做到 \(O(k\log^2k+n\log n)\)。
当 \(X\not=0\) 时:
可能会需要一些分讨,但至少也有 \(\log m\) 级别的复杂度。
True Ending
现在看来,每个问题已经圆满解决了,也没有任何优化的空间了。
但……
事实果真如此吗?
对于大部分异或问题的解决,我们似乎还有更加直接更加粗暴的方法
——没错,就是FWT!
FWT的角度
引入二元 GF。
定义 \(x\) 上的卷积为普通卷积,\(y\) 上的卷积为异或卷积。
对于模型三,转化成
模型二直接就是
模型一对 FWT 则不是特别友好,而且我们已经做到了足够优的复杂度,不予赘述。
先对模型二简单推一下式子
再做 IFWT,得到
其中 \(c_S=\sum_{i=0}^{m-1}[popcount(i\&S)\equiv 1\pmod 2]\)。
考虑 \(c_S\) 的计算:
仿照模型一的套路,枚举一个 lcp。
设 \(S\) 剩下位中有 \(w\) 个 \(1\),当前是第 \(k\) 位,lcp 中 And 出了 \(p\) 个 \(1\)。
于是就是求算
也就是
做一点观察:
当 \(w>0\) 时,上式变为 \(2^{k-1}\)。
当 \(w=0\) 时,上式变为 \(2^{k-1}(1+(-1)^{p+1})\)。
也就是说,我们从低到高位,找到第一个不为 \(0\) 的位,剩下的系数只跟之前 And 出的 \(1\) 的个数的奇偶性有关。
也就是说 \(c_S\) 的取值只有 \(O(\log m)\) 种。
枚举这个不为\(0\)的位之后,对于 \(\sum (-1)^{popcount(S\&X)}\) 的求算也是 trivial 的。
对于单个 \((1-x)^{c_S}(1+x)^{m-c_S}\) 的计算:
显然可以用 ODE 计算,求前 \(n\) 项就是 \(O(n)\) 的,求单项也可以整式递推 \(O(\sqrt n\log n)\)。
不过这里有个复合形式,尝试往拉格朗日反演的方向靠近。
先把 \((1+x)^m\) 提出去,变成求 \(F(\frac{2x}{1+x})=\sum_if_i(1-\frac{2x}{1+x})^{g_i}\)。
于是
对于前 \(n\) 项的求解,给 \(F'\) 乘上一个 \(x\) 后就是简单的卷积。
对于单项的求解,事实上不会更优,因为瓶颈在于 \(F(x)\) 的求解。
发现求 \(F(x)\) 就是对一个高次少项式的多项式平移。
不妨规约成平移常数 \(c=1\) 的问题。
那么
对其转置,得到
也就是下降幂多项式的多点求值。
我们认为 \(\log m\) 和 \(n\) 同阶,于是就可以做到 \(O(n\log ^2n)\)。
至此,完结撒花!!!