线性基(不得不填坑orz)

参见原文

ai a i 表示一个标量,而 ai a i 表示一个向量

概述

基(basis)是线性代数中的一个概念,ta是描述刻画向量空间的基本工具
而在现行的 OI 题目中,通常在利用基在异或空间中的一些特殊性质来解决题目,而这一类题目所涉及的知识点被称作「线性基」

预备知识

下面是一些线性代数的基本知识,以便更好的理解基的概念

向量空间(vector space)

定义 (F,V,+,) ( F , V , + , ⋅ ) 向量空间(vector space),其中 F F 为域,V为集合, V V 中元素称为向量,+为向量加法, 为标量乘法,且运算满足8条公理

线性无关(linearly independent)

对于向量空间中 V V n个元素的向量组 (v1,,vn) ( v 1 , … , v n ) ,若存在不全为 0 0 的数aiF,满足
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)

对于向量空间中Vn个元素的向量组(v1,,vn),其线性组合(linear combination)是如下形式的向量
a1v1+a2v2++anvn a 1 v 1 + a 2 v 2 + … + a n v n
其中 a1,,anF a 1 , … , a n ∈ F
一组向量线性无关 没有向量可用有限个其他向量的线性组合所表示

张成(span)

对于向量空间中 V V n个元素的向量组 (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 中向量组B既是线性无关的又可以张成 V V ,则称其为V基(basis)

B B 中的元素称为基向量
如果基中元素个数有限,就称向量空间为有限维向量空间,将元素的个数称作向量空间的维数

性质

B B 是向量空间 V V 的基。则B具有以下性质:

  • V V B的极小生成集,就是说只有 B B 能张成 V V ,而它的任何真子集都不张成全部的向量空间
  • B V V 中线性无关向量的极大集合,就是说B V V 中是线性无关集合,而且V中没有其他线性无关集合包含它作为真子集
  • V V 中所有的向量都可以按唯一的方式表达为B中向量的线性组合

太学术看不懂?简而言之就是一个空间的基底,空间中任意向量在该基底下都有唯一表示方法

第三点尤其重要,感性的理解,基就是向量空间中的一个子集,它可以通过唯一的线性组合,来张成向量空间中所有的向量,这样就可以大大的缩小我们向量空间的大小

线性相关性引理(Linear Dependent Lemma)

如果 (v1,,vn) ( v 1 , … , v n ) V V 中是线性相关的,并且v10,则有至少一个 j{2,,m} j ∈ { 2 , … , m } 使得下列成立:

  • vjspan(v1,,vj1) v j ∈ s p a n ( v 1 , … , v j − 1 )
  • 如果从 (v1,,vn) ( v 1 , … , v n ) 去掉第 j j 项,则剩余向量组的张成仍然等于span(v1,,vn)

证明
(v1,,vn) ( v 1 , … , v n ) V V 中是线性相关的,并且v10,则有不全为 0 0 a1,,anF,使得

a1v1++amvm=0 a 1 v 1 + … + a m v m = 0

a2,a3,,an a 2 , a 3 , … , a n ​​不会全为 0 0 (因为v10
j j {2,,m}2,,m中使得 aj0 a j ≠ 0 的最大者,那么

vj=a1ajv1aj1ajvj1 v j = − a 1 a j v 1 − … − a j − 1 a j v j − 1

这就有 (1) ( 1 ) 成立。

为了证明 (2) ( 2 ) ,设 uspan(v1,,vn) u ∈ s p a n ( v 1 , … , v n ) ,则存在 c1,,cnF 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 项的张成,因而(2)成立。

dada的blog都是天书,语言比较学术,需要多读几遍
上述知识帮助我们维护出了一个线性基的直观认识(空间中)
所谓基,就一定满足一个“必要性”,不能互相代替,缺一不可,
同时又有一定的“全面性”,用基可以推出整个世界

OI 中的线性基

异或运算下的基
求法

对于数 a0,a1,,an a 0 , a 1 , … , a n ​​ ,将 ai a i 的二进制表示 (bmb0)2 ( b m … b 0 ) 2 看作一个向量 ai=(bm,,b0) a i = ( b m , … , b 0 ) ,为了叙述上的方便,下文称向量 ai a i 的第 j j 位为bj

向量组 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,从 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 步: ajspan(a1,,aj1) a j ∈ s p a n ( a 1 , … , a j − 1 ) ,则从 B B 中去掉 aj a j ,否则保持 B B 不变。

以上步骤充分体现了基的性质以及线性相关引理

经过 n n 步后终止程序,得到一个向量组B
由于每一次去掉的向量包含于前面诸向量的张成,到最后这个组 B B 仍然可以张成 V V 。而且这一程序确保B中的任何向量都不包含与它前面诸向量的张成,根据线性相关性引理可知 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;
                }
            }
}

这个程序实现的非常精妙,我们每次维护一个对角矩阵。
执行到第i步的时候,我们从高到低考虑数 ai a i 1 1 的二进制位j,如果 j j 这一行的对角线已经为1了,那么我们不能加入,同时为了保持上三角性质,需要将第 j j 行的行向量异或到 ai
如果 j j 这一行的对角线为0,那么我们就可以将 ai a i 添加到这一行,同时为了维护一个对角矩阵,要先用下面的行消自己,再用自己消上面的行。

如果一个向量 ai a i 能被 a1,,ai1 a 1 , … , a i − 1 张成,它不应添加进 B B ,在高斯消元的过程中它必然是已经存在的行向量的线性组合,所以这个方程实际上是多余的,它最后一定会被异或为一个 0 0 。反之如果向量 ai a i 不能被 a1,,ai1 a 1 , … , a i − 1 张成,那么它一定能找到某一个行添加进去。

其实上面这两段话也不是很难懂
就是舒老师说的:倒着枚举两遍,正着枚举一遍
代码中b数组记录的实际上就是:第j位是1的线性基

我们来模拟下这个过程, n=5,a={7,1,4,3,5} n = 5 , a = { 7 , 1 , 4 , 3 , 5 }
一开始矩阵是这样的:

000000000 [ 0 0 0 0 0 0 0 0 0 ]

7=(111)2 加 入 7 = ( 111 ) 2 ,矩阵变为:

100100100 [ 1 1 1 0 0 0 0 0 0 ]

加入 1=(001)2 1 = ( 001 ) 2 ,添加到最后一行,同时为了维护对角矩阵,消去第一行的最低位,矩阵变为:

100100001 [ 1 1 0 0 0 0 0 0 1 ]

加入 4=(100)2 4 = ( 100 ) 2 ,由于第一行已经有数了,它被异或为 (010)2 ( 010 ) 2 ​​ ,加入第二行,同时为了维护对角矩阵,消去第一行的第二位,矩阵变为:

100010001 [ 1 0 0 0 1 0 0 0 1 ]

剩下的数都加不上了

这样所有被选上的 ai a i 构成一个向量空间 V V 的一个基B
同时我们知道高斯消元最后得到的矩阵 b b B中的向量构成的矩阵进行若干初等行变换得到的矩阵,而任意初等行变换不会影响向量之间的线性无关性,且任意初等行变换过后,这些向量仍然能够张成原有的向量空间(不难证明)。所以,所有非 0 0 bi b i 仍然构成向量空间 V V 的一个基。

大家所称的「线性基」一般都指这个方式得到的基,因为这个基具有一个独特的性质,可以应用到 OI 题目中。所以我们一般谈论的线性基,特指高斯消元解出的对角矩阵的非零行构成的向量组。

性质

对于最后得到的矩阵,如果第i的主对角线上为 1 1 ,此时我们称第i位存在于线性基中。对于存在于线性基的二进制位,有一个重要的性质:

对于任意存在于线性基的二进制位 i i ,至多只有一个bj满足第 i i 位为1

证明:高斯消元的过程中,我们维护了一个对角矩阵,如果二进制位 i i 存在于一个向量bj上,那么 bj b j 它一定消去了别的向量第 i i 位上的1,故二进制位 i i 只存在于bj上。

自然,对于不在线性基中的二进制位 i i ,那么第i行主对角线下方全为 0 0 ,而主对角线上方就可能有若干个1

得到线性基后我们怎么解决问题呢?

看一个例题:

给定 n(1n100000) n ( 1 ≤ n ≤ 100000 ) 个数 a1,a2,,an a 1 , a 2 , … , a n ​​ ,请问这些数能够组成的最大异或和是什么?

分析:
我们求出向量空间 V V 的一组线性基。则答案就是将线性基中所有向量异或起来得到的向量所对应的数。

考虑用归纳法证明。
因为最高的二进制位只存在于最大的基向量上(用向量所代表的二进制数来比大小),所以最大的基向量肯定要选。接着假设前i大的都需要选,考虑第 i+1 i + 1 大的基向量选不选。
显然 i+1 i + 1 大的基向量能对异或和贡献它的最高的二进制位 j j ,因为二进制位j在之前的异或和中必然为 0 0 (根据性质,j只存在于一个基向量中)。如果不选,之后所有数对答案的贡献都只能在小于这个二进制位的地方做贡献,总是比选 i+1 i + 1 得到的答案小,所以这个数必须得选。

基本操作

存在性
查询x是否存于异或集合中
从高位到低位扫描x的为1的二进制位
扫描到第i位的时候x=x^ai
如果中途x变为了0,那么表示x存于线性基的异或集合中

最大值
从高位到低位扫描线性基
如果异或后可以使得答案变大,就异或到答案中去

最小值
最小值即为最低位上的线性基

k小值
根据重要性质:

对于任意存在于线性基的二进制位 i i ,至多只有一个bj满足第 i i 位为1

所以查询的时候将k二进制拆分,对于1的位,就异或上对应的线性基。
最终得出的答案就是k小值

总结

线性基的题型相对比较固定,看到下面的类型基本上都是线性基了:

  • 最大异或和
  • k k 大异或和/异或和是第几大
  • 求所有异或值的和

线性基中的题目中还用到一个技巧:

任意一条1 n n 的路径的异或和,都可以由任意一条1 n n <script type="math/tex" id="MathJax-Element-179">n</script>路径的异或和与图中的一些环的异或和来组合得到

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值