线性基是什么?
你可以理解为将一个序列处理完之后得到的产物,并且有如下性质:1.原序列里面的任意一个数都可以由线性基里面的一些数异或得到。
2.线性基里面的任意一些数异或起来都不能得到0
3.线性基里面的数的个数唯一,并且在保持性质一的前提下,数的个数是最少的因此,线性基可以计算一段序列中异或和最大,最小,k大,或者一段序列异或后是否能构成这个数。
参考博客:
https://blog.csdn.net/a_forever_dream/article/details/83654397
https://blog.csdn.net/qaq__qaq/article/details/53812883
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Linear_Basis{
ll d[61],p[61];
int cnt;
Linear_Basis(){
memset(d,0,sizeof(d));
memset(p,0,sizeof(p));
cnt=0;
}
bool insert(ll val){
for (int i=60;i>=0;i--){
if (val&(1ll<<i)){
if (!d[i]){
d[i]=val;
break;
}
val^=d[i];
}
}
return val>0; //>0说明线性基没有这个元素
}
ll query_max(){
ll ret=0;
for (int i=60;i>=0;i--)
if ((ret^d[i])>ret)
ret^=d[i];
return ret;
}
ll query_min(){
for (int i=0;i<=60;i++)
if (d[i])
return d[i];
return 0;
}
void rebuild(){
for (int i=60;i>=0;i--)
for (int j=i-1;j>=0;j--)
if (d[i]&(1ll<<j))
d[i]^=d[j];
for (int i=0;i<=60;i++)
if (d[i])
p[cnt++]=d[i];
}
ll kthquery(ll k){
ll ret=0;
if (k>=(1LL<<cnt))
return -1;
for (int i=60;i>=0;i--)
if (k&(1LL<<i))
ret^=p[i];
return ret;
}
};
Linear_Basis merge(const Linear_Basis &n1,const Linear_Basis &n2){
Linear_Basis ret=n1;
for (int i=60;i>=0;i--)
if (n2.d[i])
ret.insert(n2.d[i]);
return ret;
}
int main(){
int n;
scanf("%d",&n);
Linear_Basis lb;
for(int i=0;i<n;i++){
ll a;
scanf("%lld",&a);
lb.insert(a);
}
printf("%lld\n",lb.query_max());
return 0;
}