【ybtoj 高效进阶 2.4】 【Trie树】 最大异或对
题目
解题思路
将每一个整数转换成二进制
用0补齐
保证每个数都是32位
将这些二进制放进数里
由异或性质可知,两个二进制数出现不同的位置越靠前,得到的结果越大
可以从高位到低位找,去判断字典树里是否存在与当前位相反的那位
有则累加进答案,顺着相反位往下找
否则顺着当前位往下找
代码
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n,x,t=1,ans,a[3200020],trie[3200020][4];
int find(int x) //找最大的异或结果
{
int p=1,da=0;
for (int i=31;i>=0;i--)
{
int c=((x>>i) & 1) == 1 ? 0 : 1; //如果为1,取0,为0则取1
if (trie[p][c]!=0) //相反位存在
da+=(int)(1<<i); //累加答案
else c=(x>>i) & 1; //顺当前位向下找
p=trie[p][c];
}
return da;
}
inline void insert() //插入
{
int p=1;
for (int i=31;i>=0;i--)
{
int c=(x>>i) & 1; //取第i位
if (!trie[p][c]) trie[p][c]=++t;
p=trie[p][c];
}
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&x);
a[i]=x;
insert();
}
for (int i=1;i<=n;i++)
{
int d=find(a[i]);
ans=max(ans,d); //求最终答案
}
printf("%d\n",ans);
return 0;
}