题意:n个数字,m个询问,问n个数字中与给定的x异或最大的数字是多少。
思路:从高位到低位插入01值,因为异或时高位尽量大,结果才尽量大,最低位节点保存相应的值,最后查询时,尽量找能使该位变成1的节点遍历。
#include <iostream>
#include <cstdio>
#include <bitset>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <set>
#include <queue>
using namespace std;
typedef long long ll;
const int INF=1e9+100;
const int mod=1e9+7;
const int N=100005;
ll ch[32*N][2],sz,val[N*32];
int n,m;
void init(){
sz=1;
memset(ch[0],0,sizeof(ch[0]));
}
void insert(ll a){
int u=0;
for(int i=32;i>=0;i--){
int c=(a>>i)&1;
if(!ch[u][c]){
memset(ch[sz],0,sizeof(ch[sz]));
//val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=a;
}
ll query(ll a){
int u=0;
for(int i=32;i>=0;i--){
int c=(a>>i)&1;
if(ch[u][c^1]) u=ch[u][c^1];
else u=ch[u][c];
}
return val[u];
}
int main(){
//freopen("out.txt","w",stdout);
int T,cas=1;
ll a;
scanf("%d",&T);
while(T--){
init();
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++){
scanf("%lld",&a);
insert(a);
}
printf("Case #%d:\n",cas++ );
while(m--){
scanf("%lld",&a);
printf("%lld\n",query(a) );
}
}
return 0;
}