1216: 异或最大值
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 367 Solved: 118
[ Submit][ Status][ Web Board]
Description
给定一些数,求这些数中两个数的异或值最大的那个值
Input
第一行为数字个数n,1 <= n <= 10 ^ 5。接下来n行每行一个32位有符号非负整数。
Output
任意两数最大异或值
Sample Input
3
3
7
9
Sample Output
14
题目分析:把每个数的二进制表示插入一颗Trie,插得时候从高位开始,这个想想就知道,然后搜的时候直接贪心,复杂度O(n)
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int const MAX = 4e6;
int n;
struct Trie
{
int root, tot, next[MAX][2], end[MAX];
inline int Newnode()
{
memset(next[tot], -1, sizeof(next[tot]));
end[tot] = 0;
return tot ++;
}
inline void Init()
{
tot = 0;
root = Newnode();
}
inline void Insert(ll x)
{
int p = root;
for(int i = 31; i >= 0; i--)
{
int idx = ((1 << i) & x) ? 1 : 0;
if(next[p][idx] == -1)
next[p][idx] = Newnode();
p = next[p][idx];
}
end[p] = x;
}
inline int Search(int x)
{
int p = root;
for(int i = 31; i >= 0; i--)
{
int idx = ((1 << i) & x) ? 1 : 0;
if(idx == 0)
p = next[p][1] != -1 ? next[p][1] : next[p][0];
else
p = next[p][0] != -1 ? next[p][0] : next[p][1];
}
return x ^ end[p];
}
}tr;
int main()
{
while(scanf("%d", &n) != EOF)
{
int ma = 0, x;
tr.Init();
for(int i = 0; i < n; i++)
{
scanf("%d", &x);
tr.Insert(x);
ma = max(ma, tr.Search(x));
}
printf("%d\n", ma);
}
}