给出n个数和m次查询,每次要从n个数中找到一个数与k的异或值最大。
因为数最大只有32位,所以我们把每个数字转化成32位2进制数。
对于每个查询的数,如果和他相反的数存在我们就沿着相反的路径往下找,
否则就沿着当前路径往下走。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<cmath>
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define inf 0x3f3f3f3f
#define LL long long
#define sca(x) scanf("%d",&x)
using namespace std;
#define N 500005
struct node
{
int f;
node* nt[3];
node()
{
f=0;
nt[0]=NULL;
nt[1]=NULL;
}
};
int a[100];
int cnt;
void dfs(int k)
{
while(k)
{
a[cnt--]=k%2;
k/=2;
}
while(cnt>=0)
{
a[cnt]=0;
cnt--;
}
}
void Insert(int k,node *root)
{
cnt=31;
dfs(k);
node *p=root;
rep(i,0,31)
{
int now=a[i];
if(!p->nt[now])
{
p->nt[now]=new node;
p=p->nt[now];
}
else p=p->nt[now];
}
}
int Find(int k,node* root)
{
cnt=31;
dfs(k);
node* p=root;
int ans[35];
int top=31;
rep(i,0,31)
{
if(p->nt[!a[i]])
{
ans[top--]=!a[i];
p=p->nt[!a[i]];
}
else
{
ans[top--]=a[i];
p=p->nt[a[i]];
}
}
int s=0;
rep(i,0,31)
{
s+=ans[i]<<i;
}
return s;
}
void del(node *root)
{
rep(i,0,1)
{
if(root->nt[i])
del(root->nt[i]);
}
delete root;
}
int main()
{
int t;
cin>>t;
int cas=1;
while(t--)
{
int n,m,tmp;
node* root=new node;
sca(n),sca(m);
rep(i,1,n)
{
sca(tmp);
Insert(tmp,root);
}
printf("Case #%d:\n",cas++);
rep(i,1,m)
{
sca(tmp);
printf("%d\n",Find(tmp,root));
}
}
del(root);
}