9.最大异或对 Trie树

Posted fx1998

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了9.最大异或对 Trie树相关的知识,希望对你有一定的参考价值。

技术图片

 可以选俩一样的数,但自己异或自己结果是0,不是最优解

预备知识,啥是异或

技术图片

 技术图片

 暴力做法就是两层for循环枚举所有可能

 暴力的思路就是

1:首先选定一个Ai(1 <= i <= n)

2:在A1 ~ An中选择一个数Aj,使得Ai ^ Aj的值最大

突破点在第2步

首先Ai一定小于等于31位,也就是0 <= Ai <= 2 ^ 31 - 1

技术图片

 本题思路:

首先对所有的Ai,根据每一位的0和1,建立一个Trie树

技术图片

 然后对于每一个固定的Ai的话

在Trie树中寻找,从根节点往下走

每次尽量往和Ai这一位上的数字不同的数字这一个分支上走,这样才能使得两个数异或出来的值最大

模拟样例

技术图片

 时间复杂度10 ^ 5 * 31

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 100010, M = 4e6 + 10;
 4 //M是Trie的总节点个数 = 10 ^ 5 * 31
 5 int a[N], son[M][2], idx;
 6 void insert(int x) {
 7     int p = 0;
 8     for (int i = 30; i >= 0; i--) {
 9         int &s = son[p][x >> i & 1];
10         if (!s) {
11             s = ++ idx; //创建新结点
12         }
13         p = s;
14     }
15 }
16 int query(int x) { //找到和x异或值最大的结果
17     int p = 0;
18     int res = 0;
19     for (int i = 30; i >= 0; i--) {
20         int s = x >> i & 1;
21         if (son[p][!s]) {
22             res += 1 << i;
23             p = son[p][!s];
24         } else {
25             p = son[p][s];
26         }
27     }
28     return res;
29 }
30 int main() {
31     int n;
32     cin >> n;
33     for (int i = 0; i < n; i++) {
34         cin >> a[i];
35         insert(a[i]);
36     }
37     int res = 0;
38     for (int i = 0; i < n; i++) {
39         res = max(res, query(a[i]));
40     }
41     cout << res << endl;
42     return 0;
43 }

 

以上是关于9.最大异或对 Trie树的主要内容,如果未能解决你的问题,请参考以下文章

算法学习——trie树求最大异或对

AcWing 143 最大异或对

143. 最大异或对

YBTOJ最大异或对

143. 最大异或对贪心 trie

143. 最大异或对(Trie树存整数+二进制)