QOJ.ac

QOJ

Type: Editorial

Status: Open

Posted by: Anonymous

Posted at: 2026-09-17 23:23:31

Last updated: 2026-09-17 23:27:10

Back to Problem

另一种做法 By ChatGPT

阅读其他语言版本: 原文 简体中文

1. 线性代数建模

把整数 $x\in[0,2^m)$ 看作 $\mathbb F_2^m$ 中的向量,异或就是向量加法。

非空集合 $A$ XOR-closed,当且仅当 $A$ 是一个线性子空间,即

$$ A=\operatorname{span}(A). $$

设我们最终选择进行操作的整数集合为 $X$,那么第 $i$ 个集合最终变成

$$ S_i\cup X. $$

要求所有 $S_i\cup X$ 都是线性子空间,并最小化 $|X|$。


2. 维护全局必需子空间 $W$

维护一个线性子空间 $W$,表示我们已经证明“最终每个集合都必须拥有”的元素。

初始令

$$ W=\{0\}. $$

因为任何非空线性子空间都必须包含 $0$。

检查每个集合

$$ A_i=S_i\cup W. $$

如果 $A_i$ 不是线性子空间,则存在

$$ x\in\operatorname{span}(S_i\cup W)\setminus(S_i\cup W). $$

这个 $x$ 在任何合法答案中都必须被操作加入。

证明如下:设某个合法答案的操作集合为 $X$。最终集合 $S_i\cup X$ 是线性子空间,并且包含 $S_i\cup W$,所以必然包含

$$ \operatorname{span}(S_i\cup W). $$

因此它包含 $x$。但 $x\notin S_i$,所以只能有 $x\in X$。一旦操作了 $x$,所有集合都会拥有 $x$。

因此可以安全地更新

$$ W\leftarrow\operatorname{span}(W\cup\{x\}). $$

因为 $x\notin W$,每次更新都会使

$$ \dim W $$

至少增加 $1$。整个空间的维数只有 $m$,所以最多更新 $m$ 次。


3. 如何判断 $S_i\cup W$ 是否闭合

$$ r_i=\dim\operatorname{span}(S_i\cup W), $$

$$ \left|\operatorname{span}(S_i\cup W)\right|=2^{r_i}. $$

另一方面,

$$ |S_i\cup W| = |S_i|+|W|-|S_i\cap W|. $$

又因为

$$ S_i\cup W\subseteq\operatorname{span}(S_i\cup W), $$

所以

$$ S_i\cup W\text{ XOR-closed} \iff |S_i|+|W|-|S_i\cap W|=2^{r_i}. $$

因此只需要为每个集合维护:

  • $r_i=\operatorname{rank}(S_i\cup W)$;
  • $t_i=|S_i\cap W|$。

不需要显式构造 $S_i\cup W$。


4. 如何找到缺失的 $x$

如果

$$ |S_i\cup W|<2^{r_i}, $$

就利用 $S_i\cup W$ 的线性基枚举其 span,找到第一个同时满足

$$ x\notin S_i,\qquad x\notin W $$

的元素即可。

看起来 span 可能很大,但只对当前找到的一个不合法集合枚举,并且找到第一个缺失元素就停止。

在找到缺失元素之前,枚举出来的所有元素都属于 $S_i\cup W$,所以一次寻找最多检查

$$ |S_i\cup W|+1 $$

个元素。


5. 如何维护 $W$

保存 $W$ 中的所有元素,并用 inW[x] 判断成员关系。

假设加入了一个满足 $x\notin W$ 的向量,那么

$$ \operatorname{span}(W\cup\{x\}) = W\cup(x\oplus W). $$

也就是说,新增加的元素恰好为

$$ \{x\oplus w\mid w\in W\}. $$

因此每次维数增加 $1$,$W$ 的大小恰好翻倍。

所有更新过程中生成的 $W$ 元素总数至多

$$ 1+2+4+\cdots+2^m=O(2^m). $$

为了维护 $|S_i\cap W|$,对每个整数 $x$ 建立倒排表,记录它原本出现在哪些集合中。当 $x$ 第一次进入 $W$ 时,更新对应集合的交集大小。


6. 维护每个集合的线性基

初始化时为每个 $S_i$ 建立线性基 $B_i$。

每次找到新的独立向量 $x$ 后,将 $x$ 插入所有 $B_i$。这样 $B_i$ 始终表示

$$ \operatorname{span}(S_i\cup W). $$

一次插入线性基的复杂度为 $O(m)$,最多更新 $m$ 次,所以这一部分复杂度为

$$ O(nm^2). $$


7. 最终答案

$$ C=\bigcap_i S_i. $$

稳定后,所有 $S_i\cup W$ 都已经是线性子空间。

但 $W$ 中原本就在所有集合里的元素不需要操作,所以输出

$$ X=W\setminus C. $$

对于任意 $i$:

$$ S_i\cup X=S_i\cup W, $$

因此答案合法。

同时,之前的推导证明了 $W$ 中任何不在所有原集合中的元素都必须被操作,所以该答案也是最优的。


8. 正确性证明

引理 1

如果当前 $W$ 是任何合法最终方案都必须共同拥有的子空间,并且

$$ x\in\operatorname{span}(S_i\cup W)\setminus(S_i\cup W), $$

那么任何合法答案都必须选择 $x$。

证明:最终的第 $i$ 个集合是一个包含 $S_i\cup W$ 的线性子空间,因此包含其 span。于是它包含 $x$。又因为 $x\notin S_i$,所以必须通过全局操作加入 $x$。证毕。

引理 2

每次更新都会使 $\dim W$ 增加 $1$。

因为选出的 $x\notin S_i\cup W$,特别地 $x\notin W$。所以

$$ \dim\operatorname{span}(W\cup\{x\}) = \dim W+1. $$

证毕。

引理 3

算法最多更新 $m$ 次。

根据引理 2,每次更新维数增加 $1$,而 $W\subseteq\mathbb F_2^m$,所以 $\dim W\le m$。证毕。

引理 4

算法结束时输出的方案合法。

结束时对所有 $i$ 都有

$$ |S_i\cup W| = 2^{\operatorname{rank}(S_i\cup W)}. $$

由于 $S_i\cup W$ 包含于它的 span,且两者大小相等,因此

$$ S_i\cup W=\operatorname{span}(S_i\cup W), $$

所以它 XOR-closed。

输出 $X=W\setminus C$。对于每个 $w\in W$:

  • 如果 $w\notin C$,则 $w\in X$;
  • 如果 $w\in C$,则 $w$ 本来就在每个 $S_i$ 中。

所以 $S_i\cup X=S_i\cup W$,答案合法。证毕。

引理 5

算法输出的操作数量最少。

根据引理 1,算法加入 $W$ 的每个独立向量都是任何合法答案所必需的。由于最终集合必须闭合,它们也必须包含这些向量张成的整个 $W$。

因此,对于每个 $w\in W\setminus C$,至少存在一个原集合不包含 $w$,任何合法答案都必须操作 $w$。

所以任何答案都至少包含 $W\setminus C$,而算法恰好输出它,故最优。证毕。


9. 复杂度

$$ M=\sum_i |S_i|. $$

时间复杂度为

$$ O(nm^2+Mm+2^m). $$

其中 $m\le 20$,可以通过。

空间复杂度为

$$ O(nm+M+2^m). $$

Comments

No comments yet.