线性空间与线性基

线性空间

1.基本概念

设向量集合 S={a1,a2,a3,...,an}

  1. 若向量 b 能由 S 进行若干次向量加法与标量乘法得到,则称 b 能被 S 表出
  2. S 能够表示出的所有向量的集合称为一个 线性空间S 称为这个线性空间的 生成子集
  3. 集合 S 中若至少存在一个向量能够被其他向量表出,则称这个向量集合 线性相关,否则称这个集合 线性无关

可以用 k 个数 a1,a2,a3,...ak 描述一个 k 维空间内的向量。

它们表示,这个向量由在第 i 个坐标轴上的长度为 ai 的向量全部相加得到。

2.线性空间的基底

线性无关的生成子集称为这个线性空间的 基底,简称

Property 1

线性空间的基底不一定唯一,但所有基底的大小均相同。

并不严谨的证明:

假设线性空间中存在两个基底 S,T,满足 |S|<|T|

由基底的定义得,S,T 能够相互表出。

|S|=n,|T|=m,那么 S 表出了一个 n 维的空间,T 表出了一个 m 维空间,且 m<n

S 也能表出一个线性无关的 T,使得 TT,|T|=|S|。则有 S 表出 TT 表出 T

由于 T 线性无关,作为子集的 T 不能表出 T,这与 “T 为基底” 矛盾。

基底的大小也称为这个线性空间的 维度

由此得到推论:

  1. 线性空间的基底加入一个同一线性空间的其他向量后,新集合一定线性相关。
  2. n 个向量作为生成子集,得到的线性空间的维数 n
  3. n 维线性空间中取一个子集 SS 的维数一定 n

Property 2

对于一个线性空间,其所有的生成子集至少存在一个子集是基底。

对于一个生成子集 S,若其中一个元素能够被其他若干元素表出,则将其删去。

重复若干次,可以得到一个线性无关的集合 T,且 T 能够表出 S

进一步地,T 是一个生成子集,也是一个基底。

由引理 1,T 的大小一定也等于线性空间的维数。

Property 3

基底是最小的生成子集。

综合引理 1 2,反证法易得。

Property 4

在线性空间中,线性无关的生成子集,等价于极大线性无关子集。

设线性无关生成子集大小为 X,极大线性无关子集大小为 Y

假设 X>Y。此时所有的线性无关子集都不是生成子集,显然矛盾。

假设 X<Y。此时所有的线性无关生成子集都不是极大的,由引理 1 得出矛盾。

则有 X=Y,亦可得出等价关系。

3.线性空间与几何

考虑如何为一维、二维、三维空间分别构造一个向量集合,使得这个集合是空间内所有向量的基底。

对每个空间坐标轴取一个单位向量,这些单位向量就是线性空间的一组基底。

考虑三维空间与三维线性空间的联系。

在线性空间中线性相关的 3 个向量,等价于在三维空间中共面或共线。

类似地,线性无关的 3 个向量等价于在三维空间中不共面或共线。

推广到 k 维线性空间,k 个线性空间中 k 个线性相关的向量,等价于它们同时处于一个小于 k 维的空间中。

另外,我们有:

  1. n 维空间内 n 个线性无关的向量构成线性空间的一组基;
  2. n 维空间的线性空间的基底大小为 n

由此建立了线性空间这一代数上的概念与几何的联系。

4.线性空间与矩阵

对于一个 n×m 的矩阵,我们把每一行看作一个 m 维向量,称这些向量为这个矩阵的 行向量

同理,我们把每一列看作一个 n 维向量,称这些向量为这个矩阵的列向量。

以行向量作为生成子集的线性空间的维度称为这个矩阵的 行秩。类似地,我们有 列秩 的定义。

Theorem

对于任意一个矩阵,其行秩与列秩相等。

Proof

考虑对矩阵 A 进行初等行变换。

初等行变换分为三种:

  1. 交换矩阵不同的两行;
  2. 把矩阵的某一行乘上一个非 0 系数加到另一行上;
  3. 对某一行乘上一个非 0 系数。

其中第 2,3 种变换对应了行向量的向量加法与标量乘法。

这意味着无论如何对矩阵做初等行变换,行向量表出的线性空间保持不变。

类似于高斯消元,利用初等行变换将原矩阵转化为对角矩阵。

全为 0 的行表示 0 向量,无法表出除 0 向量以外的任意向量,且非 0 行组成的向量集合线性无关。

于是我们得到,矩阵的行秩就是对角矩阵的非 0 行个数。

[100011000]

可以发现,对于这个对角矩阵进行初等列变换,得到列秩也等于非 0 行个数。

接下来需要证明对一个矩阵进行初等行变换之后,列向量表出的线性空间的维度不变。

m 维向量集合 S={a1,a2,a3,...,an}m 维向量 b

S 能够表出 b,当且仅当存在一组 k1,k2,...kn,满足:

{ai,1ki=b1ai,2ki=b2ai,3ki=b3ai,mki=bm

我们把这个方程组写为增广矩阵形式:

[a1,1a2,1a3,1an,1b1a1,2a2,2a3,2an,2b2a1,3a2,3a3,3an,3b3a1,ma2,ma3,man,mbm]

对这个矩阵进行初等行变换,不会对 k 是否存在产生影响。

S 变为 Sb 变为 bT,T 分别为 S,S 表出的线性空间。

对于任意的 b,若能被 S 表出,则对应的 b 也一定能够被 S 表出。故 T,T 为一组双射。

不失一般性,删去 S 中若干个元素,使得 S 变为 T 的基底,重新产生对应的 S,T。设 T 的基底为 P

假设 |S|<|P|,则 |S|<|P|。由基底的极小性,S 不可能成为 T 的生成子集,这与 T 定义矛盾。故得到 |S||P|

由初等行变换的可逆性,逆向地考虑,同理可得 |S||P|

于是有 |S|=|P|。初等行变换不会影响列向量的维度。命题得证。

回到原来的对角矩阵,它的列秩就等于原矩阵的列秩。

我们最终得到,对于任意的矩阵,行秩和列秩分别对应了对角矩阵的行秩与列秩,二者相等。

5.异或空间

设整数集合 S={a1,a2,a3,...an}

  1. b 能由 S 中若干元素经过异或运算得到,则称 b 能被 S 表出
  2. S 能够表示出的所有整数的集合称为一个 异或空间S 称为这个异或空间的 生成子集
  3. 集合 S 中若至少存在一个整数能够被其他整数表出,则称这个集合 线性相关,否则称这个集合 线性无关
  4. 异或空间的 为异或空间的线性无关生成子集,或异或空间中极大线性无关子集。

考虑如何求出异或空间的基。将每个整数看作一个 m 维二进制数,这个二进制数又表示了一个 m 维向量。

类似于普通线性空间,将这 n 个数看作 n×m 的矩阵,进行 mod2 意义下的初等行变换,转化为简化阶梯型矩阵。

例如 5,12,2,7,9n 个数得到的基为 9,5,2,过程如下:

[01011100001001111001][10010101001000000000]

void Gauss(){
    int r=1,c=63;
    for(;c>=0;c--){
        int t=0;
        for(int i=r;i<=n;i++){
            if(a[i]>>c&1){
                t=i;
                break;
            }
        }
        if(!t) continue;
        swap(a[t],a[r]);
        for(int i=1;i<=n;i++){
            if((a[i]>>c&1)&&i!=r)
                a[i]^=a[r];
        }
        r++;
    }
}

6.异或线性基的应用

Problem A

n 个整数 a1,a2,a3,...anQ 组询问,每个询问给出一个 k,求 a1,a2,...an 中选出若干个数字(不能不选)执行异或运算能够得到的整数集合中(去掉重复的数)第 k 小的整数是多少。

对这 n 个数构成的异或空间求基。设求出的基为 b1,b2,b3,...bt,并使其严格递减。

在高斯消元求基的过程中,每个 bi 代表了一个主元。主元的最高位的 1 所在的位数 ci 显然两两不同。

首先,在这 t 个数中选取一个非空子集的方案数为 2t1

如果选了 b1,由于其他的数字在第 c1 位上都是 0,那么选了 b1 得出的数字一定比没有选 b1 得出的数字大。

不选 b1 方案数为 2t11,则选择 b1 得出的最小的数是第 2t1 大。

同理,选择 b1 且选择 b2 得出的数字中最小的一个是第 2t1+2t2 大。

于是我们可以对 k 进行二进制分解。从低位到高位,若 k 的第 i 位是 1,那么就需要选择 bti

需要注意的是,题目要求的第 k 小所在的集合不能重复。

如果 a1,a2,a3,...an 进行异或运算得不出 0,则无需特判;反之,就需要跳过 0,求 b1,b2,...bt 能表出的第 k1 大的数。

题目要求的是一个 “去重异或集合”,但 a1,a2,...an 表出的是一个 ”可重异或集合“。

首先通过 b1,b2,...bt 的不同子集进行异或运算生成的数字一定两两不同,共有 2t 个,这也是异或空间的大小。

接下来我们在其余的 nt 个数字中选择若干个数字的方案数为 2nt

设其中一个子集进行异或得到的数字为 x,用 x 与基底生成的 2t 个数字分别异或,又可以得到 2t 个两两不同的数字,也就是刚好遍历了异或空间一次。

于是我们得到,”可重异或集合“ 由 ”不重异或集合“ 重复 2nt 次得到。

void Gauss(){
    zero=0;
    for(int i=1;i<=n;i++){
        int t=0; ll mx=0;
        for(int j=i;j<=n;j++){
            if(a[j]>mx){
                mx=a[j];
                t=j;
            }
        }
        if(!mx){
            zero=1,n=i-1;
            break;
        }
        swap(a[t],a[i]);
        for(int p=63;p>=0;p--){
            if(!(a[i]>>p)&1) continue;
            for(int l=1;l<=n;l++){
                if(l!=i&&(a[l]>>p&1))
                    a[l]^=a[i];
            }
            break;
        }
    }
}

void Solve(){
    read(n);
    for(int i=1;i<=n;i++) read(a[i]);
    Gauss();
    read(Q);
    while(Q--){
        ll k; read(k);
        if(zero) k--;
        if(k>=(1ll<<n)){
            puts("-1");
            continue;
        }
        ll ans=0;
        for(int i=n-1;i>=0;i--){
            if(k>>i&1)
                ans^=a[n-i];
        }
        printf("%lld\n",ans);
    }
}

Problem B

给定 n 个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大。

对这 n 个整数表出的异或空间求最简线性基,答案就是基底的每个元素的异或和。

7.数据结构与线性基

异或线性基还有一种类似于数据结构的实现方式。

bi 表示求出的基中最高位为 i 的元素,插入数字的同时维护 b

考虑如何插入一个 x。从高到低考虑 x 有值的每一位,若 bi 有值,则将 x 异或上 bi;否则,x 就成为了线性基中的一个新元素,令 bi 等于 x

注意我们维护的是一个最简的线性基。插入后,还要遍历其他的 bi,保证线性基中每一位上只有一个元素有值。

插入形式的线性基本质上与高斯消元相同,异或运算也就等价于模 2 意义下的矩阵初等行变换。

void Insert(ll x){
    for(int i=63;i>=0;i--){
        if(!(x>>i&1)) continue;
        if(!b[i]){
            for(int j=0;j<i;j++){
                if(x>>j&1)
                    x^=b[j];
            }
            for(int j=i+1;j<=63;j++){
                if(b[j]>>i&1)
                    b[j]^=x;
            }
            b[i]=x;
            return;
        }
        else x^=b[i];
    }
}
posted @   XP3301_Pipi  阅读(74)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
Title
点击右上角即可分享
微信分享提示