【题解】洛谷P10471 最大异或对 The XOR Largest Pair
洛谷P10471 最大异或对 The XOR Largest Pair
题意描述:
给定 \(N\) 个整数 \(A_1.A_2, \cdots, A_N\) 中选出两个进行异或计算,得到的结果最大是多少?
题意分析
考虑异或运算的特殊性:对于每一组进行异或运算的两个数 \((A_i,A_j)\) 的二进制位 ,相同得 \(0\) ,不同得 \(1\)
显然,我们需要尽量让两个数的二进制每一位不同(优先保证高位不同)
转化一下题目:在 \(N\) 个 \(01\) 串中寻找从高到低差异最多的一个串
因为有多个待匹配串,所以我们使用 \(Trie\) 字典树储存并查找
算法步骤
从根开始查找,令当前节点为 \(u\),查询到了第 \(i\) 位
- 如果当前节点有与 \(i\) 相反的子节点 \(v\),则向 \(v\) 转移
- 如果没有则被迫转移到与 \(i\) 相同的节点
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e6,maxc = 2;
struct TRIE {
struct node {
int val; // 这条链对应的十进制值,0表示没有这个数
int to[maxc];
};
int nodecnt = 0;
node tree[maxn + 5];
int num[40],len = 0; // 存二进制
inline void insert(int x) { // 插入
int tx = x; // 存原值
memset(num,0,sizeof(num)); len = 0; // 拆分x
while (x != 0) {
num[++ len] = x % 2;
x /= 2;
}
len = 36; // 每一个都存36位,较大值也能与较小值比较,如 111111111 ^ 0 => 111111111 ^ 000000000
int u = 0; // 字典树操作
for (int i = len;i >= 1;i --) {
int t = num[i];
if (tree[u].to[t] == 0) tree[u].to[t] = ++ nodecnt;
u = tree[u].to[t];
}
tree[u].val = tx;
}
inline int find(int x) {
int tx = x; // 存原值
memset(num,0,sizeof(num)); len = 0; // 拆分x
while (x != 0) {
num[++ len] = x % 2;
x /= 2;
}
len = 36;
int u = 0;
for (int i = len;i >= 1;i --) { // 字典树操作
int t = num[i];
if (tree[u].to[t ^ 1] != 0) u = tree[u].to[t ^ 1];
else u = tree[u].to[t];
}
return tree[u].val ^ tx; // 答案为两值异或
}
};
TRIE trie; // 字典树
int n;
int main() {
scanf("%d",&n);
int ans = 0;
for (int i = 1;i <= n;i ++) {
int x; scanf("%d",&x);
ans = max(ans,trie.find(x)); // 在前i-1个数中找
trie.insert(x); // 插入第i个数
}
printf("%d",ans);
return 0;
}

浙公网安备 33010602011771号