题目链接:https://loj.ac/problem/10050
思路:把每一个数字 x 转化为31位的二进制数,不够的前面补0,并插入到字典树中(最低为二进制位为叶节点);
接下来对每一个数字 x 的二进制位进行查找,每一步都尽量找与当前位置相反的数字进行访问,入如果有相反的数字,根据xor运算这一位就会留下一个 1 ,最后找出最大值就行。
代码:
#include<bits/stdc++.h>
#define ll long long
#define N 10086111
#define inf 0x3f3f3f3f
using namespace std;
int maxx,tot,ch[N][2];
void Init()
{
memset(ch,0,sizeof(ch));
tot=1;
}
void insertt(int x)
{
int u=1;
for(int i=30;i>=0;i--)
{
int c=x&(1<<i)?1:0;//计算出x每一位上的值
if(!ch[u][c])//如果不存在这条边
ch[u][c]=++tot;//就新建一个节点与转移边
u=ch[u][c];
}
}
int query(int x)//查询
{
int u=1,ans=0;
for(int i=30;i>=0;i--)
{
int c=x&(1<<i)?1:0;//计算x的每一位上的值
if(ch[u][!c])//如果存在与x这一位数字相反的边
{
u=ch[u][!c];
ans|=(1<<i);//把这一位上的 1 给添加到ans上
}
else
u=ch[u][c];
}
return ans;
}
int main()
{
Init();
int n;
maxx=0;
scanf("%d",&n);
while(n--)
{
int x;
scanf("%d",&x);
insertt(x);//把x的二进制插入字典树
maxx=max(maxx,query(x));
}
printf("%d\n",maxx);
return 0;
}