线性基(咕咕咕)
Tips:可以看作上三角矩阵。线性基是最小基,异或可得的元素个数是 \(2^{|p|}\)。支持 查询能否异或成 \(x\),最大异或,最小异或,\(k\) 小异或。线性基求交,线性基求并。线性基可以调整使得 非空列一定无交,也就是对于主对角线上的非零元素,其上一定为 \(0\),并且可以在插入时调整。
Tips:细节:需要记录线性基中元素能否异或成 0,对 0 必要特判。
性质
比较平凡的。
- 原序列中元素的非 \(0\) 异或值 都可以通过 线性基中的元素异或得到。
- 线性基中元素的异或值 都可以通过 原序列中的元素异或得到。
- 线性基是满足以上性质的最小集合。
- 线性基中的元素异或不会得到 \(0\)。也就是说,不同的数异或不会得到相同的异或值。
证明:假设有 \(a_1\bigoplus a_2\bigoplus ... \bigoplus a_n=0\),那么 \(a_1\) 一定可以由 \(a_2\bigoplus ... \bigoplus a_n\) 得到,那么我们把 \(a_1\) 从线性基中删除依然可以满足原有的性质,且比原来的元素个数还要少,这样原来的线性基就与第二条性质最小集合相违背,所以假设不成立。
- 线性基在异或意义上等价于原序列。
- 建出线性基后,一个很好的性质是第 \(i\) 行的线性基的前 \(1\sim i-1\) 位上的数字均为 \(0\),第 \(i\) 位为 \(1\)。
- 把两个线性基合并,等价于把原序列合并。即可以在 \(\mathcal{O}(\log \max\{w\})\) 的时间复杂度内合并两个线性基。
- 线性基支持类似 RMQ 的操作。把两个含有重复元素的线性基合并等价于不合并重复的部分。
应用
求最大异或值
对于每一位,贪心地异或。
求偶数元素最大异或值
把每个元素异或 \(a_1\) 插入线性基。
求最小异或值
一定是基中最小的元素(特判 \(0\))。
查询能否异或为给定值
每一位,不同即异或。
求 \(\bm k\) 大异或值
做法 1
调整使得 非空列无交,把 \(k\) 二进制分解找即可。
这样做会有 \(O(\log^2n)\) 的预处理复杂度。
做法 2
stO Yyc Orz
把线性基的结构看作一棵满二叉树。异或往左走,否则向右走。左边严格劣于右边。这样走即可。
注意,这样做是严格 \(O(\log n)\) 的。拜谢 Yyc!
其实和做法 1 本质相同,或是另一种表达。
线性基求并
把一个线性基中的元素暴力插入另一个。
线性基求交
顺次枚举第二个线性基 \(b\) 中的元素。考虑如果 \(b_i\text{ xor }b_{k_1}\text{ xor }b_{k_2}\text{ xor }\cdots\in a\),应有 \(b_i\in a\cup b_{1\sim i-1}\)。
带删除线性基
咕!