定义
基:在线性代数中,基(也称为基底)是描述、刻画向量空间的基本工具。向量空间的基是它的一个特殊的子集,基的元素称为基向量。向量空间中任意一个元素,都可以唯一地表示成基向量的线性组合。如果基中元素个数有限,就称向量空间为有限维向量空间,将元素的个数称作向量空间的维数。
同样的,线性基是一种特殊的基,它通常会在异或运算中出现,它的意义是:通过原集合S的某一个最小子集S1使得S1内元素相互异或得到的值域与原集合S相互异或得到的值域相同。
性质
1.线性基能相互异或得到原集合的所有相互异或得到的值。
2.线性基是满足性质1的最小的集合
3.线性基没有异或和为0的子集。
证明:
反证法:设线性基S={a1,a2...,an}
若有子集a1^a2^...^at=0,则a1=a2^a3^...^at,则舍弃a1后一定能通过剩余的元素异或出所有需要a1参与异或的值。设Y=a1^X,因为{a1,a2,...,an}是一组线性基,X一定能由a2...an中相互异或得来。
Y=a1^X=a2^a3^...^at^X,将X中在a2...at中出现的元素删去,在a2...at中未出现的元素加入,则也能异或得到Y,所以a1于线性基无用,与线性基是最小子集的定义矛盾。
所以:线性基没有异或和为0的子集。
#include<bits/stdc++.h> //万能头文件
using namespace std;
long long n,ans,a[51],b[51],m[52]; //数据是2^50,想开的更大也星
int main()
{
ios::sync_with_stdio(0); //小优化,不用在意(雾)
cin>>n;
m[0]=1; //预处理
for(int i=1;i<=51;++i)
m[i]=m[i-1]<<1;
for(int i=1;i<=n;++i) //读入数据
cin>>a[i];
//线性基标准模板
for(int i=1;i<=n;++i)
for(int j=51;j>=0;--j)
if(m[j]&a[i])
if(b[j])
a[i]^=b[j];
else
{
b[j]=a[i];
break;
}
//贪心算答案
for(int i=52;i>=0;--i)
if((ans^m[i])>ans)
ans^=b[i];
//输出
cout<<ans;
return 0;
}