题面
题目描述
给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大。
输入输出格式
输入格式:
第一行一个数n,表示元素个数
接下来一行n个数
输出格式:
仅一行,表示答案。
输入输出样例
输入样例#1:
2
1 1
输出样例#1:
1
题解
线性基模板题
以下是线性基的有关内容
1.构建
对于当前要加入线性基的数
x
x
不妨令最高位的
1
1
在第位
如果线性基中已经存在
a[p]
a
[
p
]
那么,
x=x xor a[p]
x
=
x
x
o
r
a
[
p
]
继续处理
否则,
a[p]=x
a
[
p
]
=
x
,结束操作
如果
x
x
在执行完插入操作后变成了,
证明
x
x
可以用线性基中的数的一个子集的异或和来表示
2.查询
查询某个数与线性基中任意个数的异或和的最大值
从最高位开始,依次访问每个
a[i]
a
[
i
]
,
如果
x xor a[i]>x
x
x
o
r
a
[
i
]
>
x
,
直接令
x=x xor a[i]
x
=
x
x
o
r
a
[
i
]
,继续操作即可
3.实现
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
inline ll read()
{
RG ll x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n;
struct xxj
{
ll p[60];
void insert(ll x)
{
for(int i=50;i>=0;--i)
{
if(!(x&(1ll<<i)))continue;
if(!p[i])p[i]=x;
x^=p[i];
}
}
ll Query(ll x)
{
for(int i=50;i>=0;--i)
x=max(x,x^p[i]);
return x;
}
}G;
int main()
{
n=read();
while(n--)G.insert(read());
printf("%lld\n",G.Query(0));
return 0;
}