Time Limit: 3000/1000MS (Java/Others)
Memory Limit: 131072/131072KB (Java/Others)
想对你说的话,如山似海。——AsahinaMirai
决战之后,魔法界和无魔法界分离,为了和Riko再次相见,Mirai必须用经受考验,唤醒奇迹的魔法。那考验就是——出现了n个非负整数a1,a2,…,an,
对于m次询问,第j次询问给定一个正整数xj,输出max{a1 XOR xj , a2 XOR xj , … , an XOR xj}。
XOR
运算:0 XOR 1=1,1 XOR 0=1,0 XOR 0=0,1 XOR 1=0。
按位XOR运算:对两个数的二进制位依次进行XOR运算。
还对XOR运算不懂的请去百度或谷歌一下:异或。
Input
输入的第一行为一个正整数n,
接下来一行是n个非负整数a1,a2,…,an。
接下来为一个正整数m,
接下来一行,为m个非负整数x1,x2,…,xm。
Output
输出m行,每行1个值,表示所求答案。
Sample Input
5
1 8 0 5 14
5
7 14 10 4 2
Sample Output
15
15
15
12
12
Hint
1≤n≤1000001≤n≤100000,
1≤m≤1000001≤m≤100000,
0≤ai≤21474836470≤ai≤2147483647,
0≤xi≤21474836470≤xi≤2147483647
题解:
将ai正向存入trie树中,然后对于每个xi,在trie中贪心寻找与自己不相同的最多的那个数。(判断当前位不同)
#include<bits/stdc++.h>
#define LiangJiaJun main
using namespace std;
int ch[31*100000+4][2],n,m;
int sz=0,val[31*100000+4];
int INS(int x){
int u=0,to;
for(int i=30;i>=0;i--){
to=(x>>i)&1;
if(!ch[u][to])ch[u][to]=++sz;
u=ch[u][to];
}
val[u]=x;
return 0;
}
int FIND(int x){
int u=0,to,p=~x;
for(int i=30;i>=0;i--){
to=(p>>i)&1;
if(!ch[u][to])u=ch[u][to^1];
else u=ch[u][to];
}
return x^val[u];
}
int LiangJiaJun(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int a;
scanf("%d",&a);
INS(a);
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
int x;
scanf("%d",&x);
printf("%d\n",FIND(x));
}
return 0;
}