思路:使用一个0和1的二叉树存储所有二进数,输入一个存一个再找一次,不用全部存进去后再找。为了使异或值最大,每一次查找和输入的a每一位都不同的方向(如果有的话),最后返回查找值。
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N=3e6+10;
int son[N][2],idx;
int n;
void insert(int x)
{
int p=0;
for(int i=30;i>=0;i--)
{
int u=x>>i&1;
if(!son[p][u]) son[p][u]=++idx;
p=son[p][u];
}
}
int que(int x)
{
int p=0,res=0;
for(int i=30;i>=0;i--)
{
int u=x>>i&1;
if(son[p][!u])
{
p=son[p][!u];
res=res*2+!u;
}else
{
p=son[p][u];
res=res*2+u;
}
}
return res;
}
int main()
{
cin>>n;
int a;
int res=0;
for(int i=1;i<=n;i++)
{
cin>>a;
insert(a);
int t=que(a);
res=max(res,a^t);
}
cout<<res<<endl;
return 0;
}
在查询时异或,直接返回当前数字能够异或到的最大的值,不需要得到一个返回值后再异或一次
#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
typedef unsigned long long ull;
const int N=3e6+10;
int son[N][2],idx;
int cnt[N];
string s[10010];
int flag;
void insert(int a)
{
int p=0;
for(int i=30;i>=0;i--)
{
int u=a>>i&1;
if(!son[p][u]) son[p][u]=++idx;
p=son[p][u];
}
}
int que(int x)
{
int p=0,res=0;
for(int i=30;i>=0;i--)
{
int u=x>>i&1;
if(son[p][!u])
{
p=son[p][!u];
res=res*2+1;
}else
{
p=son[p][u];
res=res*2;
}
}
return res;
}
int main()
{
int n;
scanf("%d",&n);
int sum=0;
for(int i=1;i<=n;i++)
{
int a;
scanf("%d",&a);
insert(a);
int t=que(a);
sum=max(sum,t);
}
cout<<sum<<endl;
return 0;
}