其他分享
首页 > 其他分享> > 「笔记」线性基

「笔记」线性基

作者:互联网

概念

线性基是向量空间的一组基,通常可以解决有关异或的一些题目。-Oi-wiki

线性基就是一个有着特殊性质的集合,在处理某些情况下的异或问题有着意想不到的效果。

假设我们用 \(p\) 数组来存线性基。

线性基可以由给出的一组元素相互异或而来。

而 \(p_i\) 中的元素表示该元素二进制下 \(1\) 的最高位是第 \(i\) 位。

性质

构造

一下情况都是在二进制下进行。

假设插入一个元素 \(x\) 。

把所有元素都插入后,我们就得到了这组元素的线性基。

这样构造的线性基满足它该有的所有性质,\(p_i\) 数组也符合定义。

Code:

void Insert(int k) {
    for(int i = Max; i >= 0; --i) { // Max 表示二进制最高位
        if(!(k & (1ll << i))) continue;
        if(!p[i]) { p[i] = k; return ; }
        k ^= p[i];
    }
}

操作

求最大值

给你一堆元素,挑几个异或起来,是他们的值最大,输出最大值。

我们先用这组元素构造出线性基。然后贪心的进行选择,选高位的肯定比低位的要更优。

所以我们从高位向低位遍历,如果异或上 \(p_i\) 更优就异或。最后的结果就是要求的最大值。

为什么能直接用?线性基的元素都是通过已知的元素异或而来,肯定是正确的。

Code:

int Query() {
    int res = 0; 
    for(int i = Max; i >= 0; --i) res = max(res, res^p[i]);
    return res;

求一个数是否能被表示出来

把这个数扔到线性基里跑一边就行。

每次挑这个数的最高位进行异或,都能把最高位消掉。

如果最后这个数为 \(0\) ,说明该数可以被表示出。

线性基合并

把一个线性基的每个元素插入另外一个线性基即可。

查找严格次大值

先找到最大值,然后从低位向高位枚举,然后找到两者都为一的异或上, 然后退出即可。

例题

下午再补先咕咕

鸣谢

题解 P3812 【模板】线性基 - rui_er

线性基知识整理 - Aliemo

线性基 - KnightL

标签:基中,int,res,元素,笔记,异或,线性
来源: https://www.cnblogs.com/Silymtics/p/14953835.html