场上被 T6 做局了,赛后单杀了来写篇题解。
由于只关心异或和,可以将非严格递增序列看作可重集。那么我们只关心 S 中每种元素出现次数的奇偶性。求出不可重集的方案数后每种数加入偶数个即可。我们求出 hi 表示大小为 i 且异或和在 T 中的 S 的子集个数,答案就是这样:
i=0∑∣S∣hi(∣S∣(n−i)/2+∣S∣)
我们规定 xaxb=xa⊕b,yayb=ya+b,那么可以写出 h 的生成函数:
a∈T∑[xa]b∈S∏(1+xby)
先考虑后面部分,套路地 FWT 一下变成点乘:
fk=[xk]FWT(b∈S∏(1+xby))=b∈S∏[xk]FWT(1+xby)=b∈S∏(1+y(−1)∣k∩b∣)
最后还要 IFWT 回去求出各项系数:
gk=2v1[xk]FWT(j=0∑2v−1fjxj)=2v1j=0∑2v−1[xk]FWT(fjxj)=2v1j=0∑2v−1(−1)∣k∩j∣fj=2v1j=0∑2v−1(−1)∣k∩j∣b∈S∏(1+y(−1)∣j∩b∣)
那么我们要求的东西变成了这样:
2v1a∈T∑j=0∑2v−1(−1)∣a∩j∣b∈S∏(1+y(−1)∣j∩b∣)
调换一下求和顺序:
2v1j=0∑2v−1a∈T∑(−1)∣a∩j∣b∈S∏(1+y(−1)∣j∩b∣)
注意到后面的乘积里面只有 (1−y) 和 (1+y):
caj=a∈T∑[∣a∩j∣mod2=1]cbj=b∈S∑[∣b∩j∣mod2=1]2v1j=0∑2v−1(∣T∣−2caj)(1+y)∣S∣−cbj(1−y)cbj
再次合并同类项:
i=0∑∣S∣coi(1+y)i(1−y)∣S∣−i
那么直接 O(∣S∣2) 求即可。还有一个问题是 caj 怎么快速算:考虑把所有的 ∣a∩j∣mod2 压到 bitset
里,然后每次 j←j+1 的时候相当于是反转了 j 的二进制表示的一段后缀,我们预处理出每种长度的后缀对 bitset
造成的影响,每次异或一下再调用 count()
即可做到 O(ω2v∣T∣) 求出所有 caj,cbj 同理。
那么总时间复杂度就是 O(∣S∣2+ω2v(∣S∣+∣T∣)+q∣S∣),其中 v=28,可以通过。
代码中偷懒直接写了 O(n) 预处理组合数,要规避掉也是简单的,一开始那个形式显然是一个只和 n 有关的 ∣S∣+1 次多项式,O(∣S∣2) 插值求出各项系数后也可以单次 O(∣S∣) 查询答案。好像比 std 还优一点。