异或值

异或值

给定一个长度为 $n$ 的整数序列 $a_1,a_2, \ldots, a_n$。

请你找到一个非负整数 $X$,使得 $\max\limits_{1 \leq i \leq n} \{ a_i \oplus X \}$ 的值尽可能小,其中 $\oplus$ 表示按位异或。

输出 $\max\limits_{1 \leq i \leq n} \{ a_i \oplus X \}$ 的最小可能值。

输入格式

第一行包含整数 $n$。

第二行包含 $n$ 个整数 $a_1,a_2,\ldots,a_n$。

输出格式

一个整数,表示 $\max\limits_{1 \leq i \leq n} \{ a_i \oplus X \}$ 的最小可能值。

数据范围

前 $3$ 个测试点满足 $1 \leq n \leq 3$。
所有测试点满足 $1 \leq n \leq {10}^{5}$,$0 \leq a_i \leq {2}^{30}−1$。

输入样例1:

3
1 2 3

输出样例1:

2

输入样例2:

2
1 5

输出样例2:

4

 

解题思路

  先把每个数的二进制表示用Trie存下来,然后在Trie上dfs求异或结果的最小值。

  从二进制的最高位(第$29$位)开始看,$X$的最高位有两种选择,即$0$和$1$。由于异或运算对每个位是独立的,我们可以先递归求出两棵子树(即$0$和$1$两个方向)在第$28$位到第$0$位中异或结果的最大值的最小值,假设存在且为$a$(对应$0$那个分支的子树)和$b$(对应$1$那个分支的子树)。如果$X$的最高位是$0$,那么异或结果的最大值的最小值就是$\max \{ a, b + 2^{29} \}$。同理如果$X$的最高位是$1$,那么异或结果的最大值的最小值就是$\max \{ a + 2^{29}, b \}$。最终的答案就是这两种情况的最小值,即$\min \left\{ \max \{ a, b + 2^{29} \}, \ \max \{ a + 2^{29}, b \} \right\}$。

  更一般的,如果递归到$X$的第$d$位,那么第$d$位到第$0$位的异或结果的最大值的最小值就是$$\min \left\{ \max \{ a, b + 2^{d} \}, \ \max \{ a + 2^{d}, b \} \right\}$$

  其中如果$0$对应的那个分支不存在,那么令$a = -\infty$。如果$1$对应的那个分支不存在,那么令$b = -\infty$。

  然后是时间复杂度的问题,看上去好像每层递归都有两个分支,时间复杂度为$O(2^{30})$。实则不然,因为Trie中最多只有$30 \times n$个节点,因此时间复杂度应该是$O(30 \times n)$。

  AC代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 30e5 + 10;
 5 
 6 int tr[N][2], idx;
 7 
 8 void insert(int x) {
 9     int p = 0;
10     for (int i = 29; i >= 0; i--) {
11         int t = x >> i & 1;
12         if (!tr[p][t]) tr[p][t] = ++idx;
13         p = tr[p][t];
14     }
15 }
16 
17 int dfs(int u, int d) {
18     if (d == -1) return 0;
19     int a = -2e9, b = -2e9;
20     if (tr[u][0]) a = dfs(tr[u][0], d - 1);
21     if (tr[u][1]) b = dfs(tr[u][1], d - 1);
22     return min(max(a, b + (1 << d)), max(a + (1 << d), b));
23 }
24 
25 int main() {
26     int n;
27     scanf("%d", &n);
28     while (n--) {
29         int x;
30         scanf("%d", &x);
31         insert(x);
32     }
33     printf("%d", dfs(0, 29));
34     
35     return 0;
36 }

 

参考资料

  AcWing 4869. 异或值(AcWing杯 - 周赛):https://www.acwing.com/video/4644/

posted @ 2023-03-05 20:44  onlyblues  阅读(73)  评论(0编辑  收藏  举报
Web Analytics