1.可以用于处理与异或有关的问题(异或最大值,一堆数中有无子集异或等于0,某数在一堆数异或中的排名)
2.插入操作
x=read(); for(int j=60;j>=0;j--) { //cout<<(int)((int)1<<j)<<" "; if((int)((int)1<<j)&x) { if(p[j]==0) { p[j]=x; break; } else x^=p[j]; } }
3.性质
(1)、线性基内任何子集的异或和不为0。
(2)、线性基外的所有数必能由线性基内一些数异或得到。
证明:
(1)、如果插入数x后异或和为0,则x^p1^p2^……^pt=0。则x在插入时,异或p1,p2……后即为0,就不会插入x。
(2)线性基外的数没有被插入,则肯定在中途被异或成0了,则他可以被线性基中一些数异或得到。
4.查询异或最大值:
直接在线性基中贪心,如果异或p[i]变得更大,就异或p[i]。
首先由性质(2),原序列所有数都能被线性基内的数异或得到。那么最大值一定可以通过线性基中数异或得到。
pi即表示可以异或一个二进制最高位为i的数。
如果现在ans这一位为0,那肯定异或p[i]后变得更大,如果这一位是1,那异或p[i]这一位变成0了,随便咋个异或后头的数都莫得办法变大了,那就不异或。
代码如下:

int ans=0; for(int i=52;i>=0;i--) { ans=max(ans,ans^p[i]); }
5.
查询排名第k小的数。
首先如果有异或等于0的,先把k--,因为线性基里头莫得0。然后先把p数组 ( n^{2} )预处理一哈,如果p[i]&(1<<j) p[i]^=p[j] (j=i;j>=0;j--),就保证了靠这一位影响不到后头。然后就将k转成二进制,从0枚举到最高位,如果k第i为为1,就把答案异或上p中的从0到最高位上第i个元素即可。
6.
例题
洛谷P4301
P3265 (实数线性基)
P3292