题意
在给定的 N个整数 中选出两个进行异或运算,得到的结果最大是多少?(1<=N<=1e5)
很明显这道题不能用n方暴力做,然后亦或运算是同则为0,不同为1,我们考虑把数转化为二进制之后像字符串一样存进trie树里,对于每一个数字我们要求与它亦或结果最大的那一个,于是我们在trie树上找,比如a数二进制为11001,我们就去找00110,然后为什么直接一位一位找是正确的,因为假设有01001和10110,虽然第一个只有第一位不同,但亦或结果肯定大于后者,于是就能做了。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e6+10;
int n,a[N],b[N][33],tot,ch[N][2],cnt,ans,bo[N];
int Read()
{
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f*x;
}
void insert(int k)
{
int u=0;
for(int i=1;i<=32;i++)
{
if(!ch[u][b[k][i]])
ch[u][b[k][i]]=++cnt;
u=ch[u][b[k][i]];
}
bo[u]=k;
}
int Find(int k)
{
int u=0;
for(int i=1;i<=32;i++)
{
int x;
if(b[k][i]) x=0;
else x=1;
if(ch[u][x]) u=ch[u][x];
else u=ch[u][b[k][i]];
}
return bo[u];
}
int main()
{
n=Read();
for(int i=1;i<=n;i++)
{
a[i]=Read();
int x=a[i];
tot=0;
while(x>0)
{
b[i][32-tot]=x%2;
tot++;
x/=2;
}
insert(i);
}
for(int i=1;i<=n;i++)
ans=max(ans,a[i]^a[Find(i)]);
cout<<ans;
return 0;
}