对一类异或和计数问题的探讨

对一类异或和计数问题的探讨

by AmanoKumiko


起因是 ABC288Ex,简短的题目让我从中受益很多。


该计数问题一共有三种模型。

分别是:

1.n 个数的序列,每个数在 [0,m1] 上,求异或和为 X 的方案数,设为 An

2.n 个数的集合,每个数在 [0,m1] 上,求异或和为 X 的方案数,设为 Bn

3.n 个数的多重集合,每个数在 [0,m1] 上,求异或和为 X 的方案数,设为 Cn


模型三


模型三和模型二之间有明显的关系,因为只要对第二种卷上一个 1(1x2)m 就行了。

接下来转化为每个数至多出现一次,也就是模型二的问题。


模型二


我们知道,模型一显然是一个更加可做的问题,但是缺乏模型一和二之间的对应。

不妨先假设模型二是有序序列,最后只需除掉一个阶乘。

然后考虑在模型一上容斥。

具体来说,是集合划分容斥。

我们有恒等式:

[m=1]=a1+a2++ak=mi=1k(ai1)!(1)ai1

证明也不难,因为这相当于枚举圆排列,反演一下就得证了。

现在只需强制让每个集合内的数相同,集合之间不用管。

显然只有奇数大小的集合会有贡献,而其正好就是模型一中的问题。

接下来有两条路。

第一种适用于求所有项。

wi,j 表示大小为i的序列,j 种数出现了奇数次,mj 种数出现了偶数次的方案数。

那么

wi,j=jwi1,j1+(mj)wi1,j+1

也就是枚举最后一个位置上填了什么。

那么最后有

An=i=0nwn,iBi

每项都求出来就是 O(n2) 的。

第二种使用于求单项。

考虑拉格朗日反演。

对于奇数大小的集合,最后再考虑填什么数,所以其 EGF 就是 F(x)=12(ln(1+x)ln(1x))

对于偶数大小的集合,显然每个集合都有 m 种填法,所以就是 G(x)=exp(m2ln(1x2))=(1x2)m2

然后有

Bn=i=0nAi[xn]F(x)ii!G

F(x) 的复合逆容易求解,就是 e2x1e2x+1

剩下的问题是 well-known 的,于是这一部分是 O(nlogn) 的。


模型一


接下来考虑最本源的模型一。

一个 naive 的想法是数位 dp,记录位数和顶到上界的数的个数。

单次就是 O(n2logm) 的。

显然可以有更优的做法。

枚举一个公共的 lcp,然后从当前位填 0 的数中选出一个,剩下的全部任意填。

可以发现,最后用选出的这个数一定能凑出 X

于是就是要算

i=1n[(ni)Xi(mod2)](ni)(2k)i1Skni

S 表示 m 剩余位组成的数。

稍微化简一下就可以变成幂和问题,于是就能做到单次 O(logm)

X=0 时:

k=popcount(m)

求单项时,可以做到 O(klogn)

求前 n 项时,使用分治NTT就能做到 O(klog2k+nlogn)

X0 时:

可能会需要一些分讨,但至少也有 logm 级别的复杂度。


True Ending


现在看来,每个问题已经圆满解决了,也没有任何优化的空间了。

但……

事实果真如此吗?

对于大部分异或问题的解决,我们似乎还有更加直接更加粗暴的方法

——没错,就是FWT!


FWT的角度


引入二元 GF。

定义 x 上的卷积为普通卷积,y 上的卷积为异或卷积。

对于模型三,转化成

[xnyX]1(1x2)mi=0m1(1+xyi)

模型二直接就是

[xnyX]i=0m1(1+xyi)

模型一对 FWT 则不是特别友好,而且我们已经做到了足够优的复杂度,不予赘述。

先对模型二简单推一下式子

i=0m1(S=0L11+(1)popcount(i&S)x)

再做 IFWT,得到

1LS=0L1(1)popcount(S&X)(1x)cS(1+x)mcS

其中 cS=i=0m1[popcount(i&S)1(mod2)]

考虑 cS 的计算:

仿照模型一的套路,枚举一个 lcp。

S 剩下位中有 w1,当前是第 k 位,lcp 中 And 出了 p1

于是就是求算

2kwi=0w[2|(i+1+p)](wi)

也就是

2kw21((1+1)w+(1)p+1(11)w)

做一点观察:

w>0 时,上式变为 2k1

w=0 时,上式变为 2k1(1+(1)p+1)

也就是说,我们从低到高位,找到第一个不为 0 的位,剩下的系数只跟之前 And 出的 1 的个数的奇偶性有关。

也就是说 cS 的取值只有 O(logm) 种。

枚举这个不为0的位之后,对于 (1)popcount(S&X) 的求算也是 trivial 的。

对于单个 (1x)cS(1+x)mcS 的计算:

显然可以用 ODE 计算,求前 n 项就是 O(n) 的,求单项也可以整式递推 O(nlogn)

不过这里有个复合形式,尝试往拉格朗日反演的方向靠近。

先把 (1+x)m 提出去,变成求 F(2x1+x)=ifi(12x1+x)gi

于是

[xn]F(2x1+x)=1n[xn1]F(x)(2x)n

对于前 n 项的求解,给 F 乘上一个 x 后就是简单的卷积。

对于单项的求解,事实上不会更优,因为瓶颈在于 F(x) 的求解。

发现求 F(x) 就是对一个高次少项式的多项式平移。

不妨规约成平移常数 c=1 的问题。

那么

xj=ifi(gij)

对其转置,得到

fi=jxjj!gij_

也就是下降幂多项式的多点求值。

我们认为 logmn 同阶,于是就可以做到 O(nlog2n)

至此,完结撒花!!!

posted @   冰雾  阅读(258)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示