Unverified Commit 27aa5447 authored by abc1763613206's avatar abc1763613206 Committed by GitHub
Browse files

Merge pull request #931 from cesonic/patch-10

Update basis.md
parents 5c0cb0c5 7c11e8e4
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,则能被异或出来