题意:给你一些数字,再询问Q个问题,每个问题给一个数字,使这个数字和之前给出的数字的异或和最大。
构造字典树,高位在前,低位在后
然后顺着字典树根向深处递归查询
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<iostream>
#include<functional>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, int> PLI;
const int MX = 2e5 + 5;
const int INF = 0x3f3f3f3f;
struct Node {
Node *Next[2];
Node() {
Next[0] = Next[1] = NULL;
}
};
void trie_add(Node*root, int S) {
Node *p = root;
for(int i = 31; i >= 0; i--) {
int id = ((S & (1 << i)) != 0);
if(p->Next[id] == NULL) {
p->Next[id] = new Node();
}
p = p->Next[id];
}
}
int trie_query(Node*root, int S) {
Node *p = root;
int ans = 0;
for(int i = 31; i >= 0; i--) {
int id = ((S & (1 << i)) != 0);
if(p->Next[id ^ 1] != NULL) {
ans |= (id ^ 1) << i;
p = p->Next[id ^ 1];
} else {
ans |= id << i;
p = p->Next[id];
}
}
return ans;
}
int main() {
//freopen("input.txt", "r", stdin);
int T, n, Q, t, ansk = 0;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &Q);
Node *root = new Node();
for(int i = 1; i <= n; i++) {
scanf("%d", &t);
trie_add(root, t);
}
printf("Case #%d:\n", ++ansk);
while(Q--) {
scanf("%d", &t);
printf("%d\n", trie_query(root, t));
}
}
return 0;
}