从高位向低位构造字典树,因为高位得到的数更大。
AC代码:
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=2;
struct node{
node *next[maxn];
node(){
next[0]=next[1]=NULL;
}
}*root;
LL w[50];
void deal(){
w[0]=1;
for(int i=1;i<=36;++i) w[i]=w[i-1]*2;
}
void Init(){
root = new node();
}
void insert_tree(LL num){
node *p=root,*q;
for(int i=32;i>=0;--i){
LL h=num&w[i];
int u=0;
if(h!=0) u=1;
if(p->next[u]==NULL){
q=new node();
p->next[u]=q;
p=p->next[u];
}
else {
p=p->next[u];
}
}
}
LL getAns(LL num,node *u,int lev){
if(lev<0||u==NULL) return 0;
LL ans=0;
int h=num&w[lev];
if(h!=0) h=1;
h=1-h; //xor
if(u->next[h]==NULL) ans+=(1-h)*w[lev]+getAns(num,u->next[1-h],lev-1);
else ans+=h*w[lev]+getAns(num,u->next[h],lev+-1);
return ans;
}
void free_tree(node *u){ //释放内存
if(u==NULL) return;
free_tree(u->next[0]);
free_tree(u->next[1]);
delete u;
}
int main(){
deal();
int T,n,m,kase=1;
LL x;
scanf("%d",&T);
while(T--){
Init();
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i) {
scanf("%lld",&x);
insert_tree(x);
}
printf("Case #%d:\n",kase++);
LL S;
for(int i=0;i<m;++i){
scanf("%lld",&S);
printf("%lld\n",getAns(S,root,32));
}
free_tree(root);
}
return 0;
}
如有不当之处欢迎指出!