题目链接:点击查看
题目大意:给出n个数组成的数组,再给出m个询问,每次询问给出一个x,要求从数组中选出一个k,使得k^x的值最大
题目分析:字典树求异或值最大的模板题,对于n个数直接insert到字典树中,然后对于每个查询直接贪心从树上找就是答案了,不太一样的地方是这个题目要求输出的不是答案而是原数,那么我们对于每个节点多维护一下其原来的数,也就是映射一下,最后查询的时候直接返回这个映射就是答案了
或者还有一种办法,因为异或运算的特殊性,k^x=ans,同样可以有ans^x=k,所以我们只需要对于求出来的答案再对x异或一下就是我们所要求得k了,两者等价
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int N=1e5+100;
int trie[N*35][2],cnt;
LL val[N*35];
int newnode()
{
cnt++;
trie[cnt][0]=trie[cnt][1]=0;
return cnt;
}
void insert(LL num)
{
int pos=0;
for(int i=32;i>=0;i--)
{
int to=(num>>i)&1;
if(!trie[pos][to])
trie[pos][to]=newnode();
pos=trie[pos][to];
}
val[pos]=num;
}
LL search(LL num)
{
int pos=0;
for(int i=32;i>=0;i--)
{
int to=(num>>i)&1;
if(trie[pos][!to])
pos=trie[pos][!to];
else
pos=trie[pos][to];
}
return val[pos];
}
void init()
{
trie[0][0]=trie[0][1]=0;
cnt=0;
}
int main()
{
// freopen("input.txt","r",stdin);
// ios::sync_with_stdio(false);
int w;
cin>>w;
int kase=0;
while(w--)
{
init();
int n,m;
scanf("%d%d",&n,&m);
while(n--)
{
LL num;
scanf("%lld",&num);
insert(num);
}
printf("Case #%d:\n",++kase);
while(m--)
{
LL x;
scanf("%lld",&x);
printf("%lld\n",search(x));
}
}
return 0;
}