// 11-4询问所给数与数组中所有数亦或的最大值,O(nlog32)
// 思路:构造Trie树,询问数取反后,若能在Trie树找到对应的则该位为1,否则为0
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 500000;
unsigned int x[MAXN + 10]; // 最多是2^32
struct Trie {
vector<Trie*> child;
Trie(): child(vector<Trie*>(2, NULL)) {} // 初始化子节点为Null
};
// 增加Trie树的节点
void add(int x, Trie* root) {
for (int i = 31; i >= 0; --i) { // 从最高位开始遍历
int bit = (x >> i) & 1; // bit=1最高位1,bit=0最高位0
// 如果没有对应的子节点,则新建
if (!root->child[bit]) root->child[bit] = new Trie();
root = root->child[bit]; // 更新根节点
}
}
// 反向寻找符合的数,找到为1否则为0
unsigned int search(int x, Trie* root) {
unsigned int ans = 0;
for (int i = 31; i >= 0; --i) { // 从最高位开始比
bool bit = (x >> i) & 1; // bit=1最高位1,bit=0最高位0
ans = ans << 1;
if (root->child[!bit]) {
ans++; // 如果存在匹配的点,则答案位+1
root = root->child[!bit]; // 同时顺着该点继续往下走
}
else root = root->child[bit]; // 不存在匹配的点,更新根节点
}
return ans;
}
int main() {
Trie *root = new Trie();
int n, q;
scanf("%d%d", &n, &q);
// 创建Trie树,O(n)
for (int i = 1; i <= n; i++) {
scanf("%u", x + i);
add(x[i], root);
}
// 查询对应的数
while (q--) {
unsigned int ans = 0;
unsigned int y;
scanf("%u", &y);
for (int i = 1; i <= n; i++)
ans = search(y, root); // Trie(20分,超时)
// ans = max(ans, x[i] ^ y); // 暴力解法(60分,超时)
printf("%u\n", ans);
}
return 0;
}
/*
Input
4 2
1 2 3 4
5
1
Output
7
5
*/
询问所给数与数组中所有数亦或的最大值
于 2022-07-14 12:53:33 首次发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)