问题描述
给出n个整数,多组询问求一个给出的数与这n个数中的一个数的最大异或的值。
输入格式
第一行一个整数n,表示有个数字。
第二行n个正整数。
第三行一个整数m,表示m个询问。
第四行m个整数,表示m个询问的整数。
输出格式
共m行,对于每个询问输出最大的异或值。
输入样例
4
3 5 6 7
3
1 4 7
输出样例
7
7
4
样例说明
与1异或值最大的数为6,异或值为7
与4异或值最大的数为5,异或值为7
与7异或值最大的数为3,异或值为4
限制与约定
1<= n,m <=10^5,所有数据 < 2^31-1
时间限制:1s
空间限制:256MB
贪心异或,补齐到31位的思想非常好。
Code
#include<cstdio>
#include<iostream>
using namespace std;
int edge;
int son[4000005][2];
int pd[4000005];
int cc[4000005];
int n;
inline int read()
{
char c=getchar();
while(c<'0'||c>'9')c=getchar();
int x=0;
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return x;
}
inline void add(int x)
{
int now=0;
for(int i=31;i>=1;i--)
{
int u=((1<<(i-1))&x)>>(i-1);
if(!son[now][u])
{
edge++;
son[now][u]=edge;
}
now=son[now][u];
}
pd[now]=1;
cc[now]=x;
}
inline int ask(int x)
{
int maxx=-1;
int now=0;
for(int i=31;i>=1;i--)
{
int u=((1<<(i-1))&x)>>(i-1);
if(son[now][!u])
{
now=son[now][!u];
if(pd[now])
{
maxx=max(maxx,cc[now]^x);
}
}
else
{
now=son[now][u];
if(pd[now])
{
maxx=max(maxx,cc[now]^x);
}
}
}
return maxx;
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
{
add(read());
}
int m=read();
for(int i=1;i<=m;i++)
{
printf("%d\n",ask(read()));
}
return 0;
}