NC50993 The XOR Largest Pair 0-1Trie Xor
Statement
在给定的 \(N\) 个整数 \(A_1,A_2 \dots A_N\) 中选出两个进行 \(\oplus\) 运算,得到的结果最大是多少?
Solution
建立 0-1 Trie。
0-1 Trie 是一类特殊的字典树,之所以特殊,在于其的字符集为 \(\{0,1\}\)。
由于二进制中数码也只有 \(0,1\),所以 0-1 Trie 上的一条路径可以看做一个数的二进制位。
考虑如何在 0-1 Trie 上求异或最大值。
假定我们已经确定了第一个数为 \(x\),\(x\) 的某一位为 \(0\),那么我们在 Trie 树上就要尽可能往 \(1\) 走,反之亦然。
因此,我们每读入一个数,先查询,后插入即可。
Code
#include<bits/stdc++.h>
using namespace std;
template < typename Tp >
inline void read(Tp &x) {
x = 0; int fh = 1; char ch = 1;
while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if(ch == '-') fh = -1, ch = getchar();
while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
x *= fh;
}
template < typename Tp >
inline void biread(Tp &x) {
x = 0; int fh = 1; char ch = 1;
while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if(ch == '-') fh = -1, ch = getchar();
while(ch >= '0' && ch <= '9') x = x * 2 + ch - '0', ch = getchar();
x *= fh;
}
int ch[5000000][2], cnt = 1;
inline void insert(int x) {
int p = 1;
for(int i = 30; i >= 0; i--) {
int q = ((x >> i) & 1);
if(!ch[p][q]) ch[p][q] = ++cnt;
p = ch[p][q];
}
}
inline int query(int x) {
int p = 1, res = 0;
for(int i = 30; i >= 0; i--) {
int q = ((x >> i) & 1);
if(ch[p][q ^ 1]) {
res += (1 << i);
p = ch[p][q ^ 1];
}
else if(ch[p][q]) p = ch[p][q];
else break;
}
return res;
}
int n, ans;
inline void Init(void) {
read(n);
for(int i = 1, x; i <= n; i++) {
read(x); ans = max(ans, query(x));
insert(x);
}
printf("%d\n", ans);
}
inline void Work(void) {
}
signed main(void) {
Init();
Work();
return 0;
}