Unverified Commit c1b00a96 authored by cesonic's avatar cesonic Committed by GitHub
Browse files

Update basis.md

parent 5c0cb0c5
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
线性基是向量空间的一组基,通常可以解决有关异或的一些题目。

通俗一点的讲法就是由一个集合构造出来的另一个几何,它有以下三个性质:

* 线性基的元素能相互异或得到原集合的元素的所有相互异或得到的值。

* 线性基是满足性质1的最小的集合。

* 线性基没有异或和为0的子集。

* 线性基中每个元素的异或方案唯一,也就是说,线性基中不同的异或组合异或出的数都是不一样的。

* 线性基中每个元素的二进制最高位互不相同.

构造线性基的方法如下:

对原集合的每个数p转为二进制,从高位向低位扫,对于第x位是1的,如果 $a_x$ 不存在,那么令 $a_x=p$ 并结束扫描,如果存在,令 $p=p xor a_x$。

代码:

```cpp
inline void insert(long long x){
    for(int i=55;i+1;i--){
        if(!(x>>i))//x的第i位是0
            continue;
        if(!p[i]){
            p[i]=x;
            break;
        }
        x^=p[i];
    }
}
```

查询原集合内任意几个元素xor的最大值,就可以用线性基解决。

将线性基从高位向低位扫,若xor上当前扫到的 $a_x$ 答案变大,就把答案异或上 $a_x$ 。

为什么能行呢?因为从高往低位扫,若当前扫到第i位,意味着可以保证答案的第i位为1,且后面没有机会改变第i位。

查询原集合内任意几个元素xor的最小值,就是线性基集合所有元素中最小的那个

查询某个数是否能被异或出来,类似于插入,如果最后插入的数p被异或成了0,则能被异或出来