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;
}
posted @ 2020-10-27 11:22  览遍千秋  阅读(75)  评论(0编辑  收藏  举报