题意:
给一个长度为n的序列,m个询问,每次询问给出一个数字x,问数组中哪个元素与x异或的值最大
思路:
1、我们按照长度为32位的二进制01字符串建树,从高位开始建。将所有数据都建到树中。
2、接下来对于每个查询,同样处理成35位二进制01字符串,对应进行查询,如果当前位子是0,那么尽量往1那边走,同理,如果当前位子是1,那么尽量往0那边走即可。
#include<iostream>
#include<algorithm>
#include<cstring>
const int maxn=1e5+10;
using namespace std;
struct Tire{
int ch[maxn*32][2],val[maxn*32],sz;
void init()
{
sz=0;
memset(val,0,sizeof(val));
memset(ch[0],0,sizeof(ch[0]));
}
void insert(int x)
{
int u=0;
for(int i=31;i>=0;i--){
int tem=(x>>i)&1;
if(!ch[u][tem]) ch[u][tem]=++sz;
u=ch[u][tem];
}
val[u]=x;
}
int query(int x)
{
int u=0;
for(int i=31;i>=0;i--){
int tem=(x>>i)&1;
if(!ch[u][tem^1]) u=ch[u][tem];
else u=ch[u][tem^1];
}
return val[u];
}
}Tire;
int main()
{
Tire.init();
int t,n,m,x,cas=0;
scanf("%d",&t);
while(++cas<=t){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&x),Tire.insert(x);
cout<<"Case #"<<cas<<endl;
for(int i=1;i<=m;i++) scanf("%d",&x),printf("%d\n",Tire.query(x));
}
return 0;
}
来源:https://www.cnblogs.com/overrate-wsj/p/12258135.html