最大异或对–邻接表
在给定的 N 个整数 A1,A2……AN 中选出两个进行 xor(异或)运算,得到的结果最大是多少?
输入格式 第一行输入一个整数 N。
第二行输入 N 个整数 A1~AN。
输出格式 输出一个整数表示答案。
数据范围
1≤N≤10^5,
0≤Ai<2^31
输入样例:
3
1 2 3
输出样例:
3
代码
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
const int N = 100010;//十万个数
const int M = 31*100010;//一个数,我们用31位二进制存
//n是数字个数,idx 下标,son[M][2]表示,根节点到子节点有2条路
//p表示当前的结点坐标,初始为0,表示最开始在根节点
int n, idx, son[M][2], num[N], p;
// 插入
void insert(int x) {
p = 0;
//x被化为二进制,31位
for(int i = 30; i >= 0; i--){
//二进制,最左边的位最高,题目是求最大先从最左边开始比
// & 1,二进制相同为1, 0 & 1 = 0;
int u = x >> i & 1;
//如果不存在这个结点
if(!son[p][u]) son[p][u] = ++idx;//创建
p = son[p][u];//再让p移动到这个结点
}
}
//查询
int query(int x){
p = 0;
int res = 0;
for(int i = 30; i >= 0; i--){
int u = x >> i & 1;
//u要么是1要么就是0,!1那就是0,!0就是1
//求异或的话,想最大的话就只能和u不同
if(son[p][!u])
{
p = son[p][!u];
res = res * 2 + !u;
}
//实在没有办法,那就相同
else{
p = son[p][u];
// res* 2相当于让res右移1位,+u
res = res * 2 + u;
}
}
return res;
}
int main(){
cin >> n;
int res = 0;
for(int i = 0; i < n; i++) scanf("%d", &num[i]);
for(int i = 0; i < n; i++){
//先插入,减少一句空树判断语句
insert(num[i]);
//再查询
int t = query(num[i]);
res = max(t^num[i],res);
}
printf("%d", res);
return 0;
}