题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4825
题目:
Problem Description
Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么?
Input
输入包含若干组测试数据,每组测试数据包含若干行。
输入的第一行是一个整数T(T < 10),表示共有T组数据。
每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。
输入的第一行是一个整数T(T < 10),表示共有T组数据。
每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。
Output
对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
对于每个询问,输出一个正整数K,使得K与S异或值最大。
对于每个询问,输出一个正整数K,使得K与S异或值最大。
Sample Input
2
3 2
3 4 5
1
5
4 1
4 6 5 6
3
Sample Output
Case #1:
4
3
Case #2:
4
题意:中文题
题解:01字典树
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N=100000+10; 5 int num[N],tr[32*N][2],F[32*N],tot; 6 7 void Insert(int x,int flag){ 8 int rt=0; 9 for(int i=31;i>=0;i--){ 10 int id=((x&(1<<i))!=0); 11 if(tr[rt][id]==0) tr[rt][id]=++tot; 12 rt=tr[rt][id]; 13 } 14 F[rt]=flag; 15 } 16 17 int Query(int x){ 18 int rt=0; 19 for(int i=31;i>=0;i--){ 20 int id=((x&(1<<i))!=0); 21 if(tr[rt][id^1]!=0) rt=tr[rt][id^1]; 22 else rt=tr[rt][id]; 23 } 24 return num[F[rt]]; 25 } 26 27 int main(){ 28 int t; 29 scanf("%d",&t); 30 for(int k=1;k<=t;k++){ 31 tot=0; 32 int n,m,x; 33 scanf("%d%d",&n,&m); 34 memset(F,0,sizeof(F)); 35 memset(tr,0,sizeof(tr)); 36 for(int i=1;i<=n;i++){ 37 scanf("%d",&num[i]); 38 Insert(num[i],i); 39 } 40 printf("Case #%d:\n",k); 41 for(int i=1;i<=m;i++){ 42 scanf("%d",&x); 43 printf("%d\n",Query(x)); 44 } 45 } 46 return 0; 47 }