csu1216( Trie )
csu1216
题意
给定一些数,求这些数中两个数的异或值最大的那个值。
分析
转化成二进制数存入字典树,比如说要查询 \(0011\) ,显然和 \(1100\) 结合最优,所以我们直接在字典树上寻找 \(1100\) ,如果某一位没找到不管它继续往下找,因为我们是从高到低位存的,所以找得到的一定是最优的。
code
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long ll;
using namespace std;
const int MAXN = 2e6 + 10;
int n;
int ans;
int bit[32];
struct Trie {
int nxt[MAXN][2];
int root, L;
int newnode() {
nxt[L][0] = nxt[L][1] = 0;
return L++;
}
void init() {
L = 1;
root = newnode();
}
void insert(int x) {
int tmp[32];
memset(tmp, 0, sizeof tmp);
int c = 0;
while(x) {
tmp[c++] = x % 2;
x >>= 1;
}
int now = root;
for(int i = 30; i >= 0; i--) {
int d = tmp[i];
if(!nxt[now][d]) nxt[now][d] = newnode();
now = nxt[now][d];
}
}
void query(int x) {
int tmp[32];
memset(tmp, 0, sizeof tmp);
int c = 0;
while(x) {
tmp[c++] = !(x % 2);
x >>= 1;
}
for(int i = c; i <= 30; i++) {
tmp[i] = 1;
}
int now = root;
int res = 0;
for(int i = 30; i >= 0; i--) {
int d = tmp[i];
if(nxt[now][d]) res += bit[i];
else d = !d;
now = nxt[now][d];
}
ans = max(ans, res);
}
}trie;
int main() {
bit[0] = 1;
for(int i = 1; i < 31; i++) {
bit[i] = bit[i - 1] * 2;
}
while(~scanf("%d", &n)) {
trie.init();
ans = 0;
for(int i = 0; i < n; i++) {
int x;
scanf("%d", &x);
trie.query(x);
trie.insert(x);
}
printf("%d\n", ans);
}
return 0;
}