线性基

线性基

概述

之前的记载

用于求某个序列异或和相关问题(最大、第 \(k\) 大、最小也行(不过一般不考))。

参考博客

另一个写得比较高级的博客

我们把一个长度为 \(n\) 的序列看做一个 \(n\) 维向量,线性基就是若干个这样的向量组成的线性空间的一组基,也是一组极大的线性无关向量。

通常我们动态地维护线性基来解决一些问题。

异或线性基

给你 \(n\) 个数,可以选择任意多个数异或起来,得到的数集称为一个线性空间,求线性空间的异或线性基。

我们把每个数的二进制形式看做一个 $\log $ 维的向量。线性基就是维护若干个行向量,要求行向量排成一个只有右上三角有值的正方形。

也可以简化成行简化阶梯形矩阵。

比如这样是一个行简化阶梯形矩阵线性基:

一开始线性基为空,我们依次加入每个数,每次加入数字 \(x\) 时,从上往下枚举每个向量,如果 \(x\) 的最高位已经在线性基里面有了,就对 \(x\) 做异或操作,消掉最高位。否则就加入 \(x\)

这样构造是 \(n^2 \log n\) 的。

构造代码:

其中 \(p_i\) 是最高位位 \(i\) 的基向量。

void insert(ll x) {
    per(i,bit,0) {
        if(!(x&(1ll<<i))) continue;
        if(!p[i]) return p[i]=x, void(0);
        x^=p[i];
    }
}

求序列异或和最大值

先求出线性基(行简化阶梯形矩阵)。

然后从上往下枚举每个向量,贪心地选择。如果选择这个向量结构更优就选择,否则不选。容易发现是正确的。

模板题:P3812 【模板】线性基

求线性基对应线性空间的最大值代码:

ll maxxor() {
    ll res=0;
    per(i,bit,0) res=max(res,res^p[i]);
    return res;
}

其他应用

  1. \(i\) 个向量的权值是 \(w_i\),找权值和最大的极大线性无关向量组。

    拟阵贪心,按照权值将向量从大往小排序,然后按顺序依次插入线性基即可。

  2. 线性基合并。

    启发式合并两个线性基,把小的一个一个合并到大的里面去。线性基合并就是求线性空间的并集。

  3. 求序列异或和最小值(选定集合非空)。

    就是线性基最小的那个,即最后一行向量。

  4. 询问元素 \(x\) 是否能被某个集合的异或和表示(元素 \(x\) 是否在线性空间内)。

    向线性基插入 \(x\),不能插入则说明已经在线性空间内。

  5. 求第 \(k\) 大异或和。

    维护一个行简化阶梯形矩阵。即删去空行。

    另外,每次插入元素 \(x\) 的时候,找到插入的位置之后,继续枚举低位,用低位的基消去 \(x\) 的低位。

    线性空间的大小就是 \(2\) 关于线性基大小的幂。

    \(k\) 化成二进制形式,二进制形式为 \(1\) 的那位向量就选择。

posted @ 2024-08-13 21:37  liyixin  阅读(5)  评论(0编辑  收藏  举报