1 条题解
-
0
题意理解
给定 ( n ) 个长度为 ( m ) 的 01 串集合 ( S ),和 ( q ) 个询问串 ( t )。
对每个询问,要找到一个串 ( u ),满足:- ( u = t \oplus \bigoplus_{v \in T} v ),其中 ( T \subseteq S )(即 ( u ) 可由 ( t ) 异或上 ( S ) 的某个子集得到)。
- 在满足条件 1 的所有 ( u ) 中,选择支撑序列 ( \mathrm{supp}(u) )(即所有 '1' 的位置下标)字典序最小的。
字典序定义:序列越短或第一个不同位置数值越小,字典序越小。
问题转化
-
设 ( W = \mathrm{span}(S) ) 表示 ( S ) 张成的线性空间(在 ( \mathbb{F}_2^m ) 中)。
条件 1 等价于:存在 ( w \in W ) 使得 ( u = t \oplus w )。
即 ( u ) 与 ( t ) 相差一个 ( W ) 中的向量。 -
目标:在所有 ( u \in t \oplus W ) 中,最小化 ( \mathrm{supp}(u) ) 的字典序。
由于字典序比较时,长度短优先,因此我们希望 ( u ) 的 '1' 位尽可能靠前且尽量少。
关键观察
- 字典序最小等价于:从高位到低位(位置 0 到 ( m-1 ))贪心,尽可能使该位为 0,若不能为 0 则设为 1。
- 这类似于在仿射空间 ( t + W ) 中找“最小”向量(按二进制表示的整数最小?不对,是支撑序列字典序)。
实际上,支撑序列字典序最小 ⇔ 二进制表示的整数最小(因为高位为 0 则支撑序列更短或更小)。
因此问题转化为在仿射空间中找数值最小的向量(二进制视为整数)。
算法步骤
-
计算线性基
- 对 ( S ) 中所有串构建线性基,使得基向量是“上三角”形式(即每个基向量最高位唯一,且该位以上全为 0)。
- 代码中使用
bitset存储,从高位到低位插入高斯消元。
-
标准化线性基
- 消元使得每个基向量除最高位外,其他高位(更高位)均为 0。
- 从低到高(代码中从高到低?)消元,确保基向量的最高位下方没有其他基向量的该位为 1。
-
处理询问
- 对每个询问串 ( t )(
o存储),计算前缀后缀信息s[i]:
s[i]表示用第 ( i ) 位及之后的基向量能消去的高位集合。
具体:从高位向低位扫描,若o[i]=1,则s[i] = s[i+1] ^ a[i];否则s[i] = s[i+1]。
s[0]表示用所有基向量能对o进行的变换结果。
- 对每个询问串 ( t )(
-
贪心构造
- 若
o == s[0],说明o本身在空间中可被消成全 0,则输出全 0 串(支撑序列为空,字典序最小)。 - 否则从高位向低位扫描:
a. 若当前位o[i]=0,尝试异或基向量a[i],看能否使更高位全为 0。
b. 用t标记已处理位(高位已固定),e = o & t提取未固定的高位部分。
c. 若e == s[i+1],说明剩余低位可用基向量消成 0,则保留当前o并退出;否则继续。
- 若
-
输出结果
- 最终
o即为所求u。
- 最终
正确性说明
- 标准化基向量保证了高位优先消元。
- 贪心过程确保在高位尽可能为 0 的前提下,低位可调整至全 0。
s[i]预处理加速判断:用第 ( i ) 位之后的基能否将当前向量的高位消成 0。
复杂度
- 构建线性基:( O(n m^2 / w) ),( w ) 为
bitset位数(约 64)。 - 每个询问:( O(m^2 / w) )。
- 总体可接受 ( n, m, q \leq 2000 )。
算法标签
- 线性基(高斯消元)
- 贪心构造
- 仿射空间最小化
- 字典序优化
- bitset 加速
- 1
信息
- ID
- 5771
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者