最大异或对
在给定的 N 个整数 A1,A2……AN 中选出两个进行 xor(异或)运算,得到的结果最大是多少?
输入格式
第一行输入一个整数 N。
第二行输入 N 个整数 A1~AN。
输出格式
输出一个整数表示答案。
数据范围
1≤N≤105,
0≤Ai<231
输入样例:
3
1 2 3
输出样例:
3
思路
我们最先想到的肯定是暴力,但是这题的数据范围确实比较大,因此,我们需要创建一个Tries树。
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 3000000;
int son[N][2], a[N];
int idx;
void insert(int x){
int p = 0;//p是一个指针,表示当前所在点
for(int i = 30; ~i; i--){
int &s = son[p][x >> i & 1];//&s是一个位置,是确定p要走的下一个位置
if(!s) s = ++idx;//如果说s这个结点还不存在,那么我们就创建一个新结点,idx表示一个新结点的编号
p = s;//将指针p往下挪,表示当前已经走到了下一个位置
}
}
int query(int x){
int p = 0, res = 0;
for(int i = 30; ~i; i--){//由于-1在二进制里面表示11111……1,因此,为了使代码更加简短,我们将i>=0写成~i;
int s = x >> i & 1;//s表示x的第i位(1或0)
if(son[p][!s]){//判断与x的第i位不同的分支在trie树中是否存在
res += 1 << i;//与x的第i位不同的分支在trie树中存在,则最大异或值可以加上一个1 << i(100……0);
p = son[p][!s];//p走到这个与x的第i位不同的分支
}
else p = son[p][s];//如果说与x的第i位不同的分支不存在,那么最大异或值加0(等于不加),p指针走到与x的第i位相同的分支
}
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;
return 0;
}