The XOR Largest Pair[01-Trie树 经典模板题]
The XOR Largest Pair(01-Trie 经典题)
一、题目描述
在给定的 N 个整数 A1, A2, ..., AN 中选出两个进行异或运算,问结果最大是多少?
对应题目:信息学奥赛一本通 472 【例题2】The XOR Largest Pair
二、思路分析
暴力做法
枚举所有二元组 (i, j),计算 Ai ^ Aj,取最大值。时间复杂度 O(N²),N ≤ 10⁵ 时明显超时。
01-Trie 做法
把每个整数看作一个 31 位的二进制串(因为 Ai < 2^31),从高位到低位插入一棵 Trie 树。
Trie 中每条从根到叶子的路径,就对应一个整数的二进制表示。
查询某个数 x 的最大异或值时:
- 从高位到低位逐位考虑
- 每一位都贪心地走与当前位相反的子树(因为异或相同得 0,不同得 1)
- 如果相反位不存在,只能走相同位
这样每一步都能让结果的当前位尽量为 1,最终得到的就是与 x 异或最大的数。
为什么贪心是对的
异或结果的二进制表示中,高位权重大于所有低位权重之和。
从最高位开始决策(因为 2^b > 2^b-1,高位一旦定下来,低位再怎么选都翻不了盘)。所以要 for (int b = MAXB-1; b >= 0; --b)。
所以从高位到低位贪心,每一位都尽量取 1,全局一定最优。
三、算法流程
- 预处理一个空的 Trie,根节点编号为 0
- 把每个
Ai按二进制从高位(第 30 位)到低位(第 0 位)插入 Trie - 对每个
Ai,在 Trie 中查询能与它异或得到的最大值 - 所有查询结果取最大值,即为答案
四、AC 代码
#include<bits/stdc++.h>
using namespace std;
const int MAXB = 31;
struct Node
{
int ch[2]; // ch[i] 表示下一个位置是 i 的下标
Node()
{
ch[0] = ch[1] = -1;
}
};
vector<Node> trie;
int createNode()
{
trie.emplace_back(Node());
return trie.size() - 1;
}
void insert(int t)
{
int u = 0;
for (int i = MAXB - 1; i >= 0; i--)
{
int a = (t >> i) & 1;
if (trie[u].ch[a] == -1) trie[u].ch[a] = createNode();
u = trie[u].ch[a];
}
}
int query(int x) //查询
{
int u = 0, res = 0;
for (int i = MAXB - 1; i >= 0; i--)
{
int a = (x >> i) & 1;
if (trie[u].ch[1 - a] != -1)
{
res |= 1 << i;
u = trie[u].ch[1 - a];
}
else u = trie[u].ch[a];
}
return res;
}
int main()
{
int n;
cin >> n;
trie.reserve((size_t)n * MAXB + 1); // 预留空间,避免反复扩容
createNode();
int arr[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
insert(arr[i]);
}
int res = 0;
for (int i = 0; i < n; i++)
res = max(res, query(arr[i]));
cout << res << endl;
return 0;
}
五、代码说明
1. Trie 的存储结构
struct Node
{
int ch[2]; // 只有两个子节点:0 和 1
Node() { ch[0] = ch[1] = -1; }
};
ch[0]表示当前位为 0 时的子节点ch[1]表示当前位为 1 时的子节点-1表示该子节点不存在
2. 插入
从第 30 位到第 0 位依次取出二进制位,沿 Trie 向下建立路径。
3. 查询
if (trie[u].ch[1 - a] != -1)
{
res |= 1 << i; // 当前位异或结果为 1
u = trie[u].ch[1 - a]; // 走相反位
}
else u = trie[u].ch[a]; // 只能走相同位
- 优先走相反位,让当前位异或结果为 1
- 相反位不存在时走相同位,当前位结果为 0
六、复杂度
- o(n * log(n) )
七、总结
| 要点 | 内容 |
|---|---|
| 数据结构 | 01-Trie(每个节点只有 0/1 两个儿子) |
| 核心思想 | 从高位到低位贪心走相反位 |
| 时间复杂度 | O(N × 31) |
| 关键细节 | 位数从 30 开始,最高位优先 |

浙公网安备 33010602011771号