线性基入门

线性基维护的是向量空间的一组基。在 OI 中,这种算法一般用来解决子集异或和类型的题目。

基本定义#

容易发现,异或运算本身等价于在各数位上进行模二意义下的加法。

即每一个数位看作一维,每一个数都看作一个 n 维向量。

我们相当于求 Z2n 的一组基。

首先定义什么是线性表示:

定义1:定义一整数集合(以下均指整数集合) S=x1,x2,,xn异或和 sum(s):=x1xorx2xorxn

即为所有数异或起来的结果。

注意到这里的“系数”只有零和一,所以异或就是这个线性空间里唯一的线性运算

定义2:定义一个集合 S张成 span(S)={sum(T) | TS}

S 的所有子集的异或和组成的集合。与原本的张成定义类似。

若对于集合 S0span(S),则称集合 S 线性相关。反正,则称 S 线性无关

就是如果 S 中有一个元素 Si 能被表示为其余某些元素的异或和,则这个集合 S 线性相关。

线性基#

我们称集合 BS 的线性基,当且仅当 B 满足:

  1. aS,aspan(B)
  2. B 是满足条件 1 的最小集合。

通俗来讲就是没有冗余的向量组。

构造方法#

考虑高斯消元,显然可以直接求出基底。

高斯消元的过程相当于化成三角矩阵,那么我们只要类似的构造三角矩阵即可。

我们在进行高斯消元的时候,总是确定一个行向量,然后用其他行向量去减去这个行向量来进行加减消元。

那么我们这里就直接进行异或,把这一位异或掉即可。

具体来讲,我们定义数组 p 为集合 S 的线性基,其中 pi 表示用来控制这一位为 1 的数。

考虑向 S 中加入一个数 x。从高到低考虑 x 的二进制的每一个为 1 的数位:

  • 如果 pi 不存在,说明之前的数无法使这一位为 1,直接令 pix
  • 否则,对 x 进行消元,令 xxxorpi
const int N = 105;
int n;
long long p[N], ans;
void ins(long long x) {
	for (int i = 63; i>=0; i--) {
		if (x >> i == 0) continue;
		if (!p[i]) return p[i] = x, void();
		x ^= p[i];
	}
}

应用#

查询一个数是否可被表示#

与插入类似,直接进行消元,最终消成零就说明可被表示。

查询子集异或最大/小值#

逐位考虑即可。假设消元是从大到小进行的:

对于最小值,由构造方法知道,pi 即是可被表示的最高位为 1 的数。

找到存在的最低位的 pi,容易知道这个数是唯一的。因为如果存在两个最高位都为 i 的数 a,b,那么 axorb 的最高位必定比 i 小,矛盾。

所以最小值就是这个 pi

对于最大值,显然将所有存在的维度全部变成 1 是最大的。

查询第 k#

注意到我们在查询最小值的时候利用了最低位的唯一性。

那么我们能否对线性基进行一下改造,使得其具有类似的“唯一”性质呢?

注意到,如果只使用 1,2,4,8 这一类二的幂,是必定可以构造出一组基的,而且用这一组基来构造第 k 小的方法显而易见。

从高到低考虑每一位,将 pi 异或上后面的某些 pj,使得 pi 只有最高位为一即可。

举例:

110 011 001

变成

100 010 001

然后就是简单的构造。

查询排名#

贰分。

posted @   LewisLi  阅读(91)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
主题色彩