ABC367G 题解

题意

给定正整数 \(N, M, K\) 和一个非负整数序列 \(A = (A_1, A_2, \dots, A_N)\)

对于一个非空的序列 \(B = (B_1, B_2, \dots, B_{|B|})\),我们定义它的得分为:

  • \(|B|\)\(M\) 的倍数:\((B_1 \oplus B_2 \oplus \dots \oplus B_{|B|})^K\)
  • 否则为 \(0\)

这里 \(\oplus\) 运算表示按位异或。

找到序列 \(A\)\(2^N - 1\) 个非空子序列的得分之和,对 \(998244353\) 取模。

首先考虑转化这个 \(K\) 次方,发现对于异或和很难用组合方面的知识转化,所以直接考虑对于每个 \(x\),求 \(f_x\) 表示有多少长度为 \(M\) 倍数的子序列异或和等于 \(x\)。总答案为 \(\sum\limits_{x} \left(f_x \times x^k\right)\),问题转化为求出 \(f\) 数组。

这个问题的形式很 \(\operatorname{FWT}\),更进一步,我们有 \(n\) 个幂级数 \(H_i\),第 \(i\) 个幂级数 \(\operatorname{FWT}\) 前只有 \(0\)\(A_i\) 的位置有值,因为有 \(M\) 的限制,所以我们考虑把它的系数变成一个矩阵 \(Y\),因为 \(\operatorname{FWT}\) 是一个线性变换,所以系数是整数还是矩阵都没有影响。

将每个 \(H_i\) \(\operatorname{FWT}\) 一遍后得到 \(H_i'\),将其点乘起来并 \(\operatorname{IFWT}\) 一遍后就得到了 \(f_i\) 了,时间复杂度 \(O(n V \log V)\),其中 \(V\)\(A_i\) 的值域。

考虑优化上面这个做法,容易发现每个 \(H_i\) 中只有 \(A_i\)\(0\) 的位置有值,分别是 \(Y\)\(I\),其中 \(I\) 是单位矩阵。根据 \(\operatorname{xor}\) 运算的 \(\operatorname{FWT}\) 的性质,\(H_i' = \sum_j (-1)^{\operatorname{popcount}(i ~\&~ j)} H_j\),则可以发现 \(H_i'\) 只有两种情况:\((I + Y)\)\((I - Y)\)。所以最后点乘后得到的 \(f_i'\) 一定为 \((I + Y)^a(I - Y)^b\),且 \(a + b = N\)

先用 \(O(NM)\)\(dp\) 预处理出矩阵的值(其实根本不用推出这个矩阵),只需要记 \(dp_1[i][j]\)\(dp_2[i][j]\),然后用下面的递推式推导即可:

\[\begin{cases} dp_1[i + 1][j] = dp_1[i][j] + dp_1[i][(j - 1 + M) \bmod M] \\ dp_2[i + 1][j] = dp_2[i][j] - dp_2[i][(j - 1 + M) \bmod M] \end{cases} \]

再推一个 \(G_i = \sum\limits_{j = 0}^{M - 1}dp_1[i][j] \times dp_2[N - i][(M - j) \bmod M]\),这样得到了 \((I + Y)^i(I - Y)^{N - i}\) 的值了。

接下来考虑快速得到这个 \(a\),根据 \(\operatorname{FWT}\) 的性质,如果 \(\operatorname{popcount}(x ~\&~ y)\) 为偶数,那么 \(y\) 就给 \(f_x\) 贡献了一个 \((I + Y)\)。所以计算 \(f_x\)\(a\),实际上是在计数有多少 \(A_i\) 使得 \(\operatorname{popcount}(A_i ~\&~ x)\) 为偶数。考虑使用 \(\operatorname{FWT}\) 加速这一过程,记 \(F_{i, j}\) 表示有多少 \(x\),使得 \(\operatorname{popcount}(i, x) \bmod 2 = j\),初始值 \(F_{x, 0} = cnt(x)\)(因为初始的时候相当于序列长度只有 \(1\)),其中 \(cnt(x) = \sum\limits_{i = 1}^N[x = A_i]\)

基于 \(\operatorname{FWT}\) 蝴蝶变换时的性质,当两边进行合并时刚好有 \(1\) 位不同,所以有转移(记 \(x = j + k, y = i + j + k\),其中 \(i, j, k\) 为蝴蝶变换时的三个下标):

\[\begin{cases} F'_{x, 0} = F_{x, 0} + F_{y, 0} \\ F'_{x, 1} = F_{x, 1} + F_{y, 1} \\ F'_{y, 0} = F_{x, 0} + F_{y, 1} \\ F'_{y, 1} = F_{x, 1} + F_{y, 0} \end{cases} \]

最后将 \(f'_i \gets G_{F_{i, 0}}\) 即可,\(\operatorname{IFWT}\) 一遍就得到原来的 \(f_i\) 了,总时间复杂度 \(O(NM + V \log V)\)

代码是贺的,就不放了。

posted @ 2024-08-23 02:06  CTHOOH  阅读(57)  评论(0)    收藏  举报