描述
在给定的N个整数A1,A2……AN中选出两个进行xor运算,得到的结果最大是多少?
输入格式
第一行一个整数N,第二行N个整数A1~AN。
输出格式
一个整数表示答案。
样例输入
3
1 2 3
样例输出
3
数据范围与约定
- 对于100%的数据: N<=10^5, 0<=Ai<2^31
算法分析:
题目要求寻找2个数异或的最大值,我们把每个整数看做长度为32的二进制的01串(数值较小的时候前面补0),并把A1---Ai-1(注意这里i是动态的,没一次Ai放进去之前都要查询一遍)对应的32位二进制串插入一颗Trie树(其中最低二进制位位叶子节点)。然后,关键是字典树查询代码,我们可以由异或的性质的知道,不同为1,相同为0,所以我们在查询的时候要贪心的寻找不同的,如果实在不通再按照原路线走。
代码有二进制对应的作用
代码实现:
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxnode=1000000+100;
const int sigma_size=35;
struct Trie
{
int ch[maxnode][sigma_size];
int sz;
void init()
{
sz=1;
memset(ch[0],0,sizeof(ch[0]));
}
void insert(int x)
{
int u=0;
for(int i=31;i>=0;i--)
{
int id=(x>>i)&1;//取出x二进制第i位
if(ch[u][id]==0)
{
ch[u][id]=sz;
memset(ch[sz],0,sizeof(ch[sz]));
sz++;
}
u=ch[u][id];
}
}
int find(int x)
{
int ans=0,u=0;
for(int i=31;i>=0;i--)
{
int id=(x>>i)&1;
int y=id^1; //找与id不同的
if(ch[u][y]==0)
{
u=ch[u][id];
ans<<=1; //相同为0,ans=ans*2
}
else
{
u=ch[u][y];
ans=ans<<1|1; //不同为1,ans=ans*2+1
}
}
return ans;
}
};
Trie trie;
int main()
{
trie.init();
int maxx=0;
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
maxx=max(maxx,trie.find(x));
trie.insert(x);
}
cout<<maxx<<endl;
return 0;
}