[CF1336E]Chiori and Doll Picking

题目链接

题意

给定正整数 $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\times10^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 \ne 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)$.

这个算法的时间复杂度是 $O\left(k^22^{m-k}\right)$. 和暴力拼起来就得到一个时间复杂度 $O\left(m^22^{m/2}\right)$ 的算法,可通过 $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\right)^2=2^k\hat A_i$, 也就是 $\hat A_i \in \{0, 2^k\}$.

以下借用内积的记号,令 $(i, j)$ 表示 $\mathrm{popcount}(i \mathop{\mathrm{and}} j) \bmod 2$. 我们发现 $(x, y\oplus 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$ 形如分块矩阵 $\begin{bmatrix}E_k&X\\X^{\mathrm T}&E_{m-k}\end{bmatrix}$. 那么 $\begin{bmatrix}E_k&X\end{bmatrix}\begin{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}$ 的一组基。

那么我们就可以通过枚举 $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)}\right)_0$, 也就是 $2^{-m}\sum_{i=0}^{2^m-1}\hat A_i\hat F^{(c)}_i=2^{k-m}\sum_{a=0}^mn_af(a, c)$. 这个算法的时间复杂度是 $O\left(2^{m-k}\right)$, 和暴力拼起来就得到一个时间复杂度 $O\left(2^{m/2}\right)$ 的算法,可通过 $m \le 53$ 的数据。

代码链接

猜你喜欢

转载自www.cnblogs.com/nealchen/p/12746183.html
今日推荐