【位运算】ABC281F Xor Minimization 题解

发布时间 2023-10-07 13:12:25作者: Pengzt

ABC281F

先将每一个 \(a_i\) 二进制拆分。

因为每一位的 \(\text{xor}\) 运算是互不影响的,于是可以考虑每一位。

从高位到低位考虑,因为 \(a_i < 2^{30}\),所以二进制状态下的 \(a_i\) 的长度是 \(\le 29\) 的。

假设在考虑 \(bit\) 位,则有 \(2\) 种情况:

  1. 当前考虑的所有数的第 \(bit\) 位都是 \(0\)\(1\)

  2. 当前考虑的所有数的第 \(bit\)\(0\)\(1\) 都有。

\(1\) 种情况显然可以使最后答案第 \(bit\) 位变为 \(0\)

\(2\) 种情况:数组 \(c\) 存储第 \(bit\) 位为 \(0\) 的数,数组 \(d\) 存储第 \(bit\) 位为 \(1\) 的数。

此时最后答案的第 \(bit\) 位肯定为 \(1\)

但是如果 \(x\) 的第 \(bit\) 位为 \(0\),便只需考虑 \(d\) 数组了。同理,若 \(x\) 的第 \(bit\) 位为 \(1\),便只需考虑 \(c\) 数组了。

分别搜索 \(x\)\(bit\) 位为 \(1\)\(0\) 即可。

但直接搜索参数需要传递数组,效率过低。

优化方法:排序后传递下标。

时间复杂度:\(\mathcal{O}(2^{\log_2n}+n\log n)=\mathcal{O}(n\log n)\)

代码:

const int N = 1.5 * 1e5;
int n;
int a[N + 5];
int dfs(int l, int r, int now, int bit) {
	if (l == r) return 0;
	int mid = lower_bound(a + l, a + r + 1, now | 1 << bit) - a;
	if (mid == l) return dfs(l, r, now | 1 << bit, bit - 1);
	if (mid == r + 1) return dfs(l, r, now, bit - 1);
	return min(dfs(l, mid - 1, now, bit - 1), dfs(mid, r, now | 1 << bit, bit - 1)) | 1 << bit;
}
int main () {
	n = read();
	for (int i = 1; i <= n; i++) a[i] = read();
	sort(a + 1, a + n + 1);
	n = unique(a + 1, a + n + 1) - a - 1;
	cout << dfs(1, n, 0, 29) << endl;
	return 0;
}