http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1216
Description
给定一些数,求这些数中两个数的异或值最大的那个值
Input
第一行为数字个数n,1 <= n <= 10 ^ 5。接下来n行每行一个32位有符号非负整数。
Output
任意两数最大异或值
这个问题可以用01-字典树很好地解决
即把所有数先按二进制从高到低位看成字符串插入trie。
枚举每个数,作为X,然后去trie里尽可能找每一位与X的二进制位相反的数,不断更新答案
复杂度 建树O(N*32)
查询O(n*32)
RunID | User | Problem | Result | Memory | Time | Language | Code Length | Submit Time |
---|---|---|---|---|---|---|---|---|
200255 | liuyuhong | 1216 | Accepted | 3648 | 140 | C++/Edit | 1930 B | 2016-08-10 02:38:44 |
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <vector>
using namespace std;
#define inf 2147483647
const int maxnode = 100005*32;
int len;
struct trie
{
int ch[maxnode][2];
// int val[maxnode];
int sz;
void init()
{
sz=1;
// val[0]=0; //可不需要
memset(ch[0],0,sizeof(ch[0]));
}
void insert(int s )
{
int u=0,n=31,i;
for (i=0; i<n; i++)
{
int c=s&(1<<(30-i));
c=!!c;
if (!ch[u][c])
{
memset(ch[sz],0,sizeof(ch[sz]));
// val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
// val[u]=num;
}
int query_if(int s) //查找当前单词是否存在,本题用不上
{
int ret=0;
int u=0,n=31,i;
int nex;
for (i=0; i<n; i++)
{
int c=s&(1<<(30-i));c=!!c;
if (ch[u][c^1])
c^=1;
ret|=c<<(30-i);
u=ch[u][c];
}
return ret;
}
};
trie tp;
int x[100005];
int main()
{
int n,i,j;
while(scanf("%d",&n)!=EOF)
{
tp.init();
for (i=1; i<=n; i++)
{
scanf("%d",&x[i]);
tp.insert(x[i]);
}
int ans=0;
for (i=1; i<=n; i++)
{
ans=max(ans,x[i]^tp.query_if(x[i]));
}
printf("%d\n" ,ans);//输出结果忘记取模wa几次
}
return 0;
}