在给定的 NN 个整数 A1,A2……ANA1,A2……AN 中选出两个进行 xorxor(异或)运算,得到的结果最大是多少?
输入格式
第一行输入一个整数 NN。
第二行输入 NN 个整数 A1A1~ANAN。
输出格式
输出一个整数表示答案。
数据范围
1≤N≤1051≤N≤105,
0≤Ai<2310≤Ai<231
输入样例:
3
1 2 3
输出样例:
3
题解
首先,假设我们用两个数的二进制来比较它们的大小,假设二进制的位数相同,那么我们只需要看他们的最左边是否为1,然后依次向有进行比较。
例如,2和3比较 2 10 11,它们的第一位都是1,那么我们看第二位就行,
根据上面这个,我们再求二进制的时候只需要保证从最高位开始,看有没有与它向反的,那么异或出来就是1,再加上我们从最高位开始,结果就是最大的
#include <iostream>
#include <algorithm>using namespace std;
const int M=3e7+10,N=1e5+10;
int a[N];
int son[M][2];
int idx=0;
//我们来建立一个树
// x
// 0 1
// 0 1 0 1
//第一行表示它的最高位是0还是1;void insert(int x)
{
int p=0;
for(int i=30;i>=0;i--) //因位最大时2的31次方,所以我们可以从i=30进行
{
int s=x>>i&1;
if(!son[p][s]) //如果这个不存在就创建新的节点
{
son[p][s]=++idx;
}
p=son[p][s];
}
}int query(int x)
{
int p=0;
int res=0;
for(int i=30;i>=0;i--)
{
int s=!(x>>i&1); //表示第i位与他相反的结果
if(son[p][s]) //如果存在,那么我可以顺着这个节点继续往下
{
res+=1<<i;
p=son[p][s];
}
else p=son[p][!s];
}
return res;
}int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
insert(a[i]);
}
int res=0;
for(int i=0;i<n;i++) res=max(res,query(a[i]));
cout<<res<<endl;
}