题意:给出一个数,在给定的一组数中找到与之异或值最大的数。
思路:裸01字典树,但是用之前能过5536题的模板T了(并不懂为什么,毕竟没有仔细研究模板如何实现),于是又找了一个新模板。
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <math.h>
using namespace std;
const int maxn = 100000 + 5; //集合中的数字个数
typedef long long LL;
int ch[32 * maxn][2]; //节点的边信息
LL value[32 * maxn]; //节点存储的值
int node_cnt; //树中当前节点个数
inline void init(){ //树清空
node_cnt = 1;
memset(ch[0],0,sizeof(ch));
}
inline void Insert(LL x){ //在字典树中插入 X
//和一般字典树的操作相同 将X的二进制插入到字典树中
int cur = 0;
for(int i = 32;i >= 0;--i){
int idx = (x >> i) & 1;
if(!ch[cur][idx]){
memset(ch[node_cnt],0,sizeof(ch[node_cnt]));
ch[cur][idx] = node_cnt;
value[node_cnt++] = 0;
}
cur = ch[cur][idx];
}
value[cur] = x; //最后的节点插入value
}
inline LL Query(LL x){ //在字典树中查找和X异或的最大值的元素Y 返回Y的值
int cur = 0;
for(int i = 32;i >= 0;--i){
int idx = (x >> i) & 1;
if(ch[cur][idx ^ 1]) cur = ch[cur][idx ^ 1];
else cur = ch[cur][idx];
}
return value[cur];
}
int main(){
int t;
scanf("%d", &t);
for(int cas=1;cas<=t;cas++){
init();
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
LL a;
scanf("%lld",&a);
Insert(a);
}
printf("Case #%d:\n",cas);
for(int i=0;i<m;i++){
int b;
scanf("%lld",&b);
printf("%lld\n",Query(b));
}
}
return 0;
}