携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情
AcWing 143. 最大异或对
在给定的 N 个整数 A1,A2……AN 中选出两个进行 xor(异或)运算,得到的结果最大是多少?
输入格式
第一行输入一个整数 N。
第二行输入 N 个整数 A1~AN。
输出格式
输出一个整数表示答案。
数据范围
1 ≤ N ≤ 10^5,
0 ≤ Ai < 2^31
输入样例:
3
1 2 3
输出样例:
3
思路
题意
1 的 二进制 001
2 的 二进制 010
3 的 二进制 011
两个数字异或,最大值为 1 ^ 2 = 3
方法使用字典树
字典树不单单可以高效存储和查找字符串集合,还可以存储二进制数字
思路:将每个数以二进制方式存入字典树,找的时候从最高位去找有无该位的异.
ac代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010, M = 3100010; //M表示一个数字串二进制的长度
int n;
int a[N], son[M][2], idx;
void insert(int x){
int p = 0; //根节点
for (int i = 30; i >= 0; i -- ){ //逆序,因为要从最高位开始存储
int &s = son[p][x >> i & 1]; //取x的第 i 位的二进制是什么 x >> k & 1,从最高位开始存储
if (!s) s = ++ idx; //如果没有该节点就新建一个节点
p = s; //指针指向下一层
}
}
int search(int x){
int p = 0, res = 0;
for (int i = 30; i >= 0; i -- ){ //逆序,从最高位开始
int s = x >> i & 1; //从最高位开始找
if (son[p][!s]){ //如果当前层有对应的不相同的数
res += 1 << i;
p = son[p][!s];
}
else p = son[p][s]; //没有相异的
}
return res;
}
int main(){
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, search(a[i]));
cout << res;
return 0;
}