标签:
/**
异或最大值(01字典树)
题意:求n个非负数中任意2个的异或值的最大值。n数量级为10^5
分析:直接暴力肯定超时了。一个非负整数可以看成1个32位的01字符串,n个数可以看成n个字符串,因此可以建立字典树,
建好树后,对于任意非负整数x,可以沿着树根往下贪心找到y,使得x异或y最大,复杂度为树的深度。
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn=3200010;
int n;
int a[100010];
int node;
int next[maxn][2];
int End[maxn];
void add(int cur, int k)
{
memset(next[node],0,sizeof(next[node]));
End[node]=0;
next[cur][k]=node++;
}
int cal(int x)
{
int k,cur=0;
for(int i=30;i>=0;i--)
{
int k=!((1<<i)&x);
if(next[cur][k])
cur=next[cur][k];
else
cur=next[cur][k^1];
}
return (x^End[cur]);
}
int main()
{
while(~scanf("%d",&n))
{
node=1;
memset(next[0],0,sizeof(next[0]));
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
int x=a[i],cur=0;
for(int j=30;j>=0;j--)
{
int k=((1<<j)&x);
if(next[cur][k]==0)
add(cur,k);
cur=next[cur][k];
}
End[cur]=x;
}
int ans=-1;
for(int i=0;i<n;i++)
{
ans=max(ans,cal(a[i]));
}
printf("%d\n",ans);
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/45286949