1.题目链接。题意:给定一个数组和N组询问,每组询问输出一下这个数组里和该元素异或的最大值。
2.字典树的应用,把数位当作字符串然后建一棵01字典树,这个数的高度最多是32层,然后对于每个数,找出数位之后,贪心的在树上找和它数位不一样的地方,从高位开始找,这样异或起来数值一定是最大的。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int MAXN = 100010;
int tol;
LL val[32 * MAXN];
int ch[32 * MAXN][2];
void init()
{
tol = 1;
ch[0][0] = ch[0][1] = 0;
}
void insert(LL x)
{
int u = 0;
for (int i = 32; i >= 0; i--)
{
int v = (x >> i) & 1;
if (!ch[u][v])
{
ch[tol][0] = ch[tol][1] = 0;
val[tol] = 0;
ch[u][v] = tol++;
}
u = ch[u][v];
}
val[u] = x;
}
LL query(LL x)
{
int u = 0;
for (int i = 32; i >= 0; i--)
{
int v = (x >> i) & 1;
//利用贪心策略,优先寻找和当前位不同的数
if (ch[u][v ^ 1]) u = ch[u][v ^ 1];
else u = ch[u][v];
}
return val[u]; //返回结果
}
int main()
{
int T;
scanf("%d", &T);
for (int ca = 1; ca <= T; ca++)
{
int M, N;
scanf("%d%d", &M, &N);
init();
int tem;
for (int i = 0; i < M; i++)
{
scanf("%d", &tem);
insert(tem);
}
printf("Case #%d:\n", ca);
while (N--)
{
scanf("%d", &tem);
LL ans = query(tem);
printf("%lld\n", ans);
}
}
}