/** 异或最大值(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; }
时间: 2024-10-27 07:59:28