题目描述
在给定的 N 个整数 A1,A2……AN 中选出两个进行异或运算,得到的结果最大是多少?
输入
第一行一个整数 N,第二行 N 个整数 A1−AN。
输出
输出一个整数表示答案。
样例输入
3
1 2 3
样例输出
3
样例输入
10
181262 369842 1036879 546331 868986 496157 646816 459571 215643 448018
样例输出
1033222
数据规模与约定
时间限制:1 s
内存限制:256 M
100% 的数据保证 N≤105
解题思路
寻找2个数异或的最大值,我们把每个整数看做长度为32的二进制的01串(数值较小的时候前面补0),并把A1---Ai-1对应的32位二进制串插入一颗Trie树(其中最低二进制位位叶子节点)。之后对于Ai对应的32位二进制串,在Trie中进行一次与检索类似的过程,每一步都尝试沿着与Ai的当前位相反的字符指针进行向下访问,若与Ai的当前位相反的字符指针指向空节点,则只好访问与Ai当前位相同的字符指针.
代码演示
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const ll INF=1e12;
const int MAXN=4e6+5;
int n,m,tot,ans;
int trie[MAXN][2];
int cnt[MAXN];
void iinsert(int x)
{
int p=0;
for(int i=31;i>=0;i--){
int c=(x>>i)&1;
if(!trie[p][c])
trie[p][c]=++tot;
p=trie[p][c];
}
}
int isearch(int x)
{
int p=0,ans=0;
for(int i=31;i>=0;i--){
int c=(x>>i)&1,o=c^1;
if(trie[p][o])
p=trie[p][o],ans=ans<<1|1;
else
p=trie[p][c],ans<<=1;
}
return ans;
}
int main()
{
int n,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
ans=max(ans,isearch(x));
iinsert(x);
}
printf("%d\n",ans);
return 0;
}
编译器运行结果
10
181262 369842 1036879 546331 868986 496157 646816 459571 215643 448018
1033222