线性基
线性基
概述
我们把一个长度为 \(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;
}
其他应用
-
第 \(i\) 个向量的权值是 \(w_i\),找权值和最大的极大线性无关向量组。
拟阵贪心,按照权值将向量从大往小排序,然后按顺序依次插入线性基即可。
-
线性基合并。
启发式合并两个线性基,把小的一个一个合并到大的里面去。线性基合并就是求线性空间的并集。
-
求序列异或和最小值(选定集合非空)。
就是线性基最小的那个,即最后一行向量。
-
询问元素 \(x\) 是否能被某个集合的异或和表示(元素 \(x\) 是否在线性空间内)。
向线性基插入 \(x\),不能插入则说明已经在线性空间内。
-
求第 \(k\) 大异或和。
维护一个行简化阶梯形矩阵。即删去空行。
另外,每次插入元素 \(x\) 的时候,找到插入的位置之后,继续枚举低位,用低位的基消去 \(x\) 的低位。
线性空间的大小就是 \(2\) 关于线性基大小的幂。
把 \(k\) 化成二进制形式,二进制形式为 \(1\) 的那位向量就选择。
本文来自博客园,作者:liyixin,转载请注明原文链接:https://www.cnblogs.com/liyixin0514/p/18357751