题目背景
这是一道模板题。
题目描述
给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大。
输入格式
第一行一个数n,表示元素个数
接下来一行n个数
输出格式
仅一行,表示答案。
输入输出样例
输入 #1复制
2
1 1
输出 #1复制
1
说明/提示
1 \leq n \leq 50, 0 \leq S_i \leq 2 ^ {50}1≤n≤50,0≤S
i
≤2
50
具体讲解可以参考
XOR HDU - 3949(线性基/高斯消元/异或第k大) ACWING210. 异或运算
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
ll f[105];
int p,cnt;
void insert(ll x)
{
for(int i = 63;i >= 0;i--)
{
if((x >> i) & 1)//从高位到低位
{
if(!f[i])//第i位没有,赋值为x
{
f[i] = x;
break;
}
x ^= f[i];//第i位有,去掉x的第i位
}
}
}
void build()
{
for(int i = 0;i <= 63;i++)//高斯消元
{
for(int j = i + 1;j <= 63;j++)
{
if((f[j] >> i) & 1)f[j] ^= f[i];
}
}
cnt = 0;
for(int i = 0;i <= 63;i++)
{
if(f[i])
f[cnt++] = f[i];
}
}
ll query()
{
ll res = 0;
for(int i = 63;i >= 0;i--)
{
res = max(res,res ^ f[i]);
}
return res;
}
int main()
{
int n;scanf("%d",&n);
for(int i = 1;i <= n;i++)
{
ll x;scanf("%lld",&x);
insert(x);
}
build();
printf("%lld\n",query());
return 0;
}