CodeForces -1285D Dr. Evil Underscores(01trie,树形dp)

题目链接

题目大意

  找一个数使这个数分别与每个数异或,其中的最大值最下。

解题思路

  可以先建一个01trie,然后在01trie上dp。如果当前位只有1或者0的话,对答案就没有贡献;如果两者都有,那么取最大值的时候肯定要加上这一位,那么答案就是这一位再加上两颗子树中的最小值。

代码

const int maxn = 1e5+10;
const int maxm = 2e6+10;
int trie[maxm][2], arr[maxn], tot = 0;
void insert(int num) {
	int p = 0;
	for (int i = 29; i>=0; --i) {
		int t = num>>i&1;
		if (!trie[p][t]) trie[p][t] = ++tot;
		p = trie[p][t]; 
	}
}
int solve(int now, int p) {
	if (now<0) return 0;
	if (trie[p][1]&&trie[p][0]) return (1<<now) + min(solve(now-1, trie[p][1]), solve(now-1, trie[p][0]));
	else if (trie[p][1]) return solve(now-1, trie[p][1]);
	else return solve(now-1, trie[p][0]);
}
int main() {
	int n; cin >> n;
	for (int i = 1; i<=n; ++i) {
		cin >> arr[i];
		insert(arr[i]);
	}
	cout << solve(29, 0) << endl;
	return 0;
}
posted @ 2021-02-03 20:51  shuitiangong  阅读(63)  评论(0编辑  收藏  举报