ai a i 表示一个标量,而 ai a i 表示一个向量
概述
基(basis)是线性代数中的一个概念,ta是描述刻画向量空间的基本工具
而在现行的 OI 题目中,通常在利用基在异或空间中的一些特殊性质来解决题目,而这一类题目所涉及的知识点被称作「线性基」
预备知识
下面是一些线性代数的基本知识,以便更好的理解基的概念
向量空间(vector space)
定义 (F,V,+,⋅) ( F , V , + , ⋅ ) 为向量空间(vector space),其中 F F 为域,为集合, V V 中元素称为向量,为向量加法, ⋅ ⋅ 为标量乘法,且运算满足8条公理
线性无关(linearly independent)
对于向量空间中
V
V
上个元素的向量组
(v1,…,vn)
(
v
1
,
…
,
v
n
)
,若存在不全为
0
0
的数,满足
a1v1+a2v2+…+anvn=0
a
1
v
1
+
a
2
v
2
+
…
+
a
n
v
n
=
0
则称这
n
n
个向量线性相关(linearly dependent),否则称为线性无关(linearly independent)
线性组合(linear combination)
对于向量空间中V上n个元素的向量组,其线性组合(linear combination)是如下形式的向量
a1v1+a2v2+…+anvn
a
1
v
1
+
a
2
v
2
+
…
+
a
n
v
n
其中
a1,…,an∈F
a
1
,
…
,
a
n
∈
F
一组向量线性无关
⇔
⇔
没有向量可用有限个其他向量的线性组合所表示
张成(span)
对于向量空间中 V V 上个元素的向量组 (v1,…,vn) ( v 1 , … , v n ) ,其所有线性组合所构成的集合称为 (v1,…,vn) ( v 1 , … , v n ) 的张成(span),记为 span(v1,…,vn) s p a n ( v 1 , … , v n )
基(basis)
若向量空间 V V 中向量组既是线性无关的又可以张成 V V ,则称其为的基(basis)
B
B
中的元素称为基向量
如果基中元素个数有限,就称向量空间为有限维向量空间,将元素的个数称作向量空间的维数
性质
设 B B 是向量空间 V V 的基。则具有以下性质:
- V V 是的极小生成集,就是说只有 B B 能张成 V V ,而它的任何真子集都不张成全部的向量空间
- 是 V V 中线性无关向量的极大集合,就是说在 V V 中是线性无关集合,而且中没有其他线性无关集合包含它作为真子集
- V V 中所有的向量都可以按唯一的方式表达为中向量的线性组合
太学术看不懂?简而言之就是一个空间的基底,空间中任意向量在该基底下都有唯一表示方法
第三点尤其重要,感性的理解,基就是向量空间中的一个子集,它可以通过唯一的线性组合,来张成向量空间中所有的向量,这样就可以大大的缩小我们向量空间的大小
线性相关性引理(Linear Dependent Lemma)
如果 (v1,…,vn) ( v 1 , … , v n ) 在 V V 中是线性相关的,并且,则有至少一个 j∈{2,…,m} j ∈ { 2 , … , m } 使得下列成立:
- vj∈span(v1,…,vj−1) v j ∈ s p a n ( v 1 , … , v j − 1 )
- 如果从 (v1,…,vn) ( v 1 , … , v n ) 去掉第 j j 项,则剩余向量组的张成仍然等于
证明
设
(v1,…,vn)
(
v
1
,
…
,
v
n
)
在
V
V
中是线性相关的,并且,则有不全为
0
0
的,使得
a1v1+…+amvm=0 a 1 v 1 + … + a m v m = 0
a2,a3,…,an
a
2
,
a
3
,
…
,
a
n
不会全为
0
0
(因为)
设
j
j
是中使得
aj≠0
a
j
≠
0
的最大者,那么
vj=−a1ajv1−…−aj−1ajvj−1 v j = − a 1 a j v 1 − … − a j − 1 a j v j − 1
这就有 (1) ( 1 ) 成立。
为了证明 (2) ( 2 ) ,设 u∈span(v1,…,vn) u ∈ s p a n ( v 1 , … , v n ) ,则存在 c1,…,cn∈F c 1 , … , c n ∈ F ,使得
u=c1v1+…+cnvn
u
=
c
1
v
1
+
…
+
c
n
v
n
在上面的等式中,可以用之前的等式右边来代替
vj
v
j
。这样
u
u
包含于从
(v0,…,vn)
(
v
0
,
…
,
v
n
)
去掉第
j
j
项的张成,因而成立。
dada的blog都是天书,语言比较学术,需要多读几遍
上述知识帮助我们维护出了一个线性基的直观认识(空间中)
所谓基,就一定满足一个“必要性”,不能互相代替,缺一不可,
同时又有一定的“全面性”,用基可以推出整个世界
OI 中的线性基
异或运算下的基
求法
对于数 a0,a1,…,an a 0 , a 1 , … , a n ,将 ai a i 的二进制表示 (bm…b0)2 ( b m … b 0 ) 2 看作一个向量 ai=(bm,…,b0) a i = ( b m , … , b 0 ) ,为了叙述上的方便,下文称向量 ai a i 的第 j j 位为
向量组 a1,…,an a 1 , … , a n 可以张成一个向量集合 span(a1,…,an) s p a n ( a 1 , … , a n ) ,加上我们的异或运算和乘法运算(显然满足 8 条公理),即可形成一个向量空间 V=({0,1},span(a1,…,an),⊕,⋅) V = ( { 0 , 1 } , s p a n ( a 1 , … , a n ) , ⊕ , ⋅ )
我们考虑求出向量空间 V V 的一个基,从 B=(a1,…,an) B = ( a 1 , … , a n ) 开始
也就是说,我们现在有n个数字,异或和为X,
我们现在需要构造一个尽量小的集合,集合中的数字异或和也为X
这样两者效应是一样的
为了构造目标集合,我们就需要从原先的n个数字开始
第 1 步:如果
a1=0
a
1
=
0
,则从
B
B
中去掉
a1
a
1
,否则保持
B
B
不变
第 j 步:若
aj∈span(a1,…,aj−1)
a
j
∈
s
p
a
n
(
a
1
,
…
,
a
j
−
1
)
,则从
B
B
中去掉
aj
a
j
,否则保持
B
B
不变。
以上步骤充分体现了基的性质以及线性相关引理
经过
n
n
步后终止程序,得到一个向量组
由于每一次去掉的向量包含于前面诸向量的张成,到最后这个组
B
B
仍然可以张成
V
V
。而且这一程序确保中的任何向量都不包含与它前面诸向量的张成,根据线性相关性引理可知
B
B
是线性无关的。于是
B
B
是
V
V
的一个基。
利用高斯消元来判断向量能否被前面的向量张成,就可以写出下面的程序:
消法一般有两种,一种是直接消成上三角阵,一种是消成对角线阵
第一种跑得比较快,但第二种贪心起来比较简单,各有利弊
//三角阵
for (int i=1;i<=n;i++)
{
int t=a[i];
for (int j=30;j>=0;j--)
if (t>>j&1) //t的j位为1
if (!b[j])
{
b[j]=t; //j这位为1的基底
break;
}
else t^=b[j];
}
//对角线阵
void cal() {
for (int i=1;i<=n;i++)
for (int j=MAX_BASE;j>=0;j--)
if (a[i]&(1<<j)) {
if (b[j]) a[i]^=b[j];
else {
b[j]=a[i]; //第j位为1的基底
for (int k=j-1;k>=0;k--)
if (b[k]&&(b[j]&(1<<k))) b[j]^=b[k];
for (int k=j+1;k<=MAX_BASE;k++)
if (b[k]&(1<<j)) b[k]^=b[j];
break;
}
}
}
这个程序实现的非常精妙,我们每次维护一个对角矩阵。
执行到第步的时候,我们从高到低考虑数
ai
a
i
为
1
1
的二进制位,如果
j
j
这一行的对角线已经为了,那么我们不能加入,同时为了保持上三角性质,需要将第
j
j
行的行向量异或到 ;
如果
j
j
这一行的对角线为,那么我们就可以将
ai
a
i
添加到这一行,同时为了维护一个对角矩阵,要先用下面的行消自己,再用自己消上面的行。
如果一个向量 ai a i 能被 a1,…,ai−1 a 1 , … , a i − 1 张成,它不应添加进 B B ,在高斯消元的过程中它必然是已经存在的行向量的线性组合,所以这个方程实际上是多余的,它最后一定会被异或为一个 0 0 。反之如果向量 ai a i 不能被 a1,…,ai−1 a 1 , … , a i − 1 张成,那么它一定能找到某一个行添加进去。
其实上面这两段话也不是很难懂
就是舒老师说的:倒着枚举两遍,正着枚举一遍
代码中b数组记录的实际上就是:第j位是1的线性基
我们来模拟下这个过程,
n=5,a={7,1,4,3,5}
n
=
5
,
a
=
{
7
,
1
,
4
,
3
,
5
}
一开始矩阵是这样的:
加入7=(111)2 加 入 7 = ( 111 ) 2 ,矩阵变为:
加入 1=(001)2 1 = ( 001 ) 2 ,添加到最后一行,同时为了维护对角矩阵,消去第一行的最低位,矩阵变为:
加入 4=(100)2 4 = ( 100 ) 2 ,由于第一行已经有数了,它被异或为 (010)2 ( 010 ) 2 ,加入第二行,同时为了维护对角矩阵,消去第一行的第二位,矩阵变为:
剩下的数都加不上了
这样所有被选上的
ai
a
i
构成一个向量空间
V
V
的一个基。
同时我们知道高斯消元最后得到的矩阵
b
b
是中的向量构成的矩阵进行若干初等行变换得到的矩阵,而任意初等行变换不会影响向量之间的线性无关性,且任意初等行变换过后,这些向量仍然能够张成原有的向量空间(不难证明)。所以,所有非
0
0
的
bi
b
i
仍然构成向量空间
V
V
的一个基。
大家所称的「线性基」一般都指这个方式得到的基,因为这个基具有一个独特的性质,可以应用到 OI 题目中。所以我们一般谈论的线性基,特指高斯消元解出的对角矩阵的非零行构成的向量组。
性质
对于最后得到的矩阵,如果第的主对角线上为 1 1 ,此时我们称第位存在于线性基中。对于存在于线性基的二进制位,有一个重要的性质:
对于任意存在于线性基的二进制位 i i ,至多只有一个满足第 i i 位为。
证明:高斯消元的过程中,我们维护了一个对角矩阵,如果二进制位 i i 存在于一个向量上,那么 bj b j 它一定消去了别的向量第 i i 位上的,故二进制位 i i 只存在于上。
自然,对于不在线性基中的二进制位 i i ,那么第行主对角线下方全为 0 0 ,而主对角线上方就可能有若干个。
得到线性基后我们怎么解决问题呢?
看一个例题:
给定 n(1≤n≤100000) n ( 1 ≤ n ≤ 100000 ) 个数 a1,a2,…,an a 1 , a 2 , … , a n ,请问这些数能够组成的最大异或和是什么?
分析:
我们求出向量空间
V
V
的一组线性基。则答案就是将线性基中所有向量异或起来得到的向量所对应的数。
考虑用归纳法证明。
因为最高的二进制位只存在于最大的基向量上(用向量所代表的二进制数来比大小),所以最大的基向量肯定要选。接着假设前大的都需要选,考虑第
i+1
i
+
1
大的基向量选不选。
显然
i+1
i
+
1
大的基向量能对异或和贡献它的最高的二进制位
j
j
,因为二进制位在之前的异或和中必然为
0
0
(根据性质,只存在于一个基向量中)。如果不选,之后所有数对答案的贡献都只能在小于这个二进制位的地方做贡献,总是比选
i+1
i
+
1
得到的答案小,所以这个数必须得选。
基本操作
存在性
查询x是否存于异或集合中
从高位到低位扫描x的为1的二进制位
扫描到第i位的时候x=x^ai
如果中途x变为了0,那么表示x存于线性基的异或集合中
最大值
从高位到低位扫描线性基
如果异或后可以使得答案变大,就异或到答案中去
最小值
最小值即为最低位上的线性基
k小值
根据重要性质:
对于任意存在于线性基的二进制位 i i ,至多只有一个满足第 i i 位为
所以查询的时候将k二进制拆分,对于1的位,就异或上对应的线性基。
最终得出的答案就是k小值
总结
线性基的题型相对比较固定,看到下面的类型基本上都是线性基了:
- 最大异或和
- 第 k k 大异或和/异或和是第几大
- 求所有异或值的和
线性基中的题目中还用到一个技巧:
任意一条到 n n 的路径的异或和,都可以由任意一条到 n n <script type="math/tex" id="MathJax-Element-179">n</script>路径的异或和与图中的一些环的异或和来组合得到