题目链接
题意
给定正整数 $a_1, a_2, ldots, a_n$, 保证 $a_i<2^m$. 任取其中若干个(可以不取,下同),对于 $c=0, 1, ldots, m$ 求有多少种取法使得取出的正整数的异或和(如果不取,异或和为 $0$, 下同)恰有 $c$ 位为 $1$. 两种取法不同当且仅当取的下标不同,答案对 $998\,244\,353$ 取模。
限制:$n le 2 imes10^5$. 简单版 $m le 35$, 困难版 $m le 53$.
题解
别人都能当场A掉简单版,只有我啥都不会的神题。
把数看成域 $mathbb F_2$ 下的一个 $m$ 维向量,标号为 $i$ 的(从 $0$ 开始标号,下同)分量为 $1$ 当且仅当该数第 $2^i$ 位为 $1$. 异或可以看成是向量加法。
那么由 $a_1, a_2, ldots, a_n$ 可扩张出一个向量空间 $V$. 用类似消元第一步的方法处理 $a_1, a_2, ldots, a_n$ 得到 $V$ 的一组基 $b_1, b_2, ldots, b_k$. 我们发现对于 $i e j$, 操作 $a_i gets a_i oplus a_j$ 不影响答案,所以求出来的基 $b_1, b_2, ldots, b_k$ 加上 $(n-k)$ 个零向量与 $a_1, a_2, ldots, a_n$ 是等效的。零向量取或者不取对答案没有影响,所以只需求 $b_1, b_2, ldots, b_k$ 对应的答案,最后各乘以 $2^{n-k}$ 就好了。
有一个显然的暴力是用深搜枚举 ${b_1, b_2, ldots, b_k}$ 的子集并求出各子集异或和,用分段打表法算 $1$ 的位数。该算法的时间是 $O(2^k)$.
用一般的方法求基,将得到一个 $m$ 阶上三角方阵 $M$, 其中非零的行向量就构成一组基。不妨设主对角线上前 $k$ 行列都有非零元素。再用高斯消元将前 $k$ 行前 $k$ 列消成单位矩阵,那么前 $k$ 个行向量仍然是一组基。
简单版:设 $f(i, j, T)$ 表示 $b_1, b_2, ldots, b_i$ 中选了 $j$ 个,且后 $m-k$ 位的异或和为 $T$ 的选法数。那么一个状态 $(k, j, T)$ 中 $1$ 的位数为 $j+mathrm{popcount}(T)$.
这个算法的时间复杂度是 $Oleft(k^22^{m-k} ight)$. 和暴力拼起来就得到一个时间复杂度 $Oleft(m^22^{m/2} ight)$ 的算法,可通过 $m le 35$ 的数据。
困难版:设集合幂级数 $A$ 的第 $i$ 项为 $A_i=[i in V]$. 我们发现,若固定 $x in V$, 当 $i$ 遍历 $V$ 的所有元素时,有 $x oplus i$ 也遍历 $V$ 的所有元素。换句话说,我们得到 $A * A=2^kA$, 其中 $*$ 运算是异或卷积。设 $A$ 的沃尔什变换为 $hat A$, 其第 $i$ 项为 $hat A_i$(以后记号类似),那么 $left(hat A_i ight)^2=2^khat A_i$, 也就是 $hat A_i in {0, 2^k}$.
以下借用内积的记号,令 $(i, j)$ 表示 $mathrm{popcount}(i mathop{mathrm{and}} j) mod 2$. 我们发现 $(x, yoplus z) equiv (x, y)+(x, z) pmod 2$.
考虑 $hat A_i$ 何时为 $2^k$. 由于 $hat A_i=sum_{j in V}(-1)^{(i,j)}$, 若存在 $x in V$ 使得 $(i, x) equiv 1 pmod 2$, 那么我们可以知道当 $j$ 遍历 $V$ 时,$x oplus j$ 也遍历了 $V$, 那么 $hat A_i=-hat A_i$, 即 $hat A_i=0$. 反之,若 $forall j in V$, $(i, j) equiv 0 pmod 2$, 显然有 $hat A_i=2^k$.
那么我们考虑求出那些满足 $forall j in V$, $(x, j) equiv 0 pmod 2$ 的 $x$. 所有 $x$ 构成一个 $mathbb F_2^m$ 的子空间,类似于 $V$ 的正交补,这里也记作 $V^{perp}$. 但是由于这不是真正的内积函数,$(x, x) equiv 0 pmod 2$ 不能导出 $x=0$, 无法用施密特正交化的方法求 $V^{perp}$.
求法是这样的:将 $M$ 的后 $m-k$ 行 $m-k$ 列填上单位矩阵。然后根据 $M$ 的右上角将左下角对称补齐,得到一个对称矩阵 $M=M^{mathrm T}$. 那么其后 $m-k$ 列就是 $V^{perp}$ 的一组基 $B$.
证明比较显然:假设 $M$ 形如分块矩阵 $egin{bmatrix}E_k&X\X^{mathrm T}&E_{m-k}end{bmatrix}$. 那么 $egin{bmatrix}E_k&Xend{bmatrix}egin{bmatrix}X\E_{m-k}end{bmatrix}=X+X=O$, 也就是 $forall i in {b_1, b_2, ldots, b_k}, forall j in B$, 均有 $(i, j) equiv 0 pmod 2$. 根据内积的结合律即得 $B$ 是 $V^{perp}$ 的一组基。
(经过EntropyIncreaser提示,可以把基构成的矩阵看成一个线性变换,那么上述做法实际上就是求该线性变换的零空间)。
那么我们就可以通过枚举 $B$ 的子集来确定 $hat A_i$ 中的非零元素了。$V^{perp}$ 中有 $n_c$ 个含有 $c$ 位 $1$.
已知 $hat A_i$, 我们设集合幂级数为 $F^{(c)}_i=[mathrm{popcount}(i)=c]$, 根据定义可得 $hat F^{(c)}_i=sum_{mathrm{popcount}(j)=c}(-1)^{(i, j)}$, 我们发现位之间顺序无所谓,所以设 $i$ 有 $a$ 位 $1$, 并枚举 $i mathop{mathrm{and}} j$ 有 $b$ 位 $1$, 可得 $hat F^{(c)}_i=sum_{b=0}^c(-1)^b{a choose b}{m-a choose c-b}$, 将此值记为 $f(a, c)$.
那么 $c$ 对应的答案是 $left(A_i * F^{(c)} ight)_0$, 也就是 $2^{-m}sum_{i=0}^{2^m-1}hat A_ihat F^{(c)}_i=2^{k-m}sum_{a=0}^mn_af(a, c)$. 这个算法的时间复杂度是 $Oleft(2^{m-k} ight)$, 和暴力拼起来就得到一个时间复杂度 $Oleft(2^{m/2} ight)$ 的算法,可通过 $m le 53$ 的数据。