HDU4825 Xor Sum(贪心+Trie树)
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
题解:
今天本来想写一个可持久化Trie树,发现这道题一直没做就补上了。
其实思路很简单,假如说两个数,和同一个数异或,很显然,由于进制,高位上的一个1可以大于低位上所有1,所以即使后面的情况再糟糕,也比取后面好的值高(其实就是1000比0111大)
所以可以建一个01线段树,从高往低插入一个数,比较时取反即可^_^
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int n,m,t; 6 struct pnt{ 7 int child[2]; 8 int end; 9 void res() 10 { 11 memset(child,0,sizeof(child)); 12 end=0; 13 } 14 }; 15 struct Trie{ 16 pnt tr[3300000]; 17 int siz; 18 void dst() 19 { 20 siz=0; 21 tr[0].res(); 22 } 23 void insert(int x,int l) 24 { 25 int root=0; 26 for(int i=31;i>=0;i--) 27 { 28 int tmp=(bool)((x&(1<<i))!=0); 29 if(!tr[root].child[tmp]) 30 { 31 tr[root].child[tmp]=++siz; 32 tr[siz].res(); 33 } 34 root=tr[root].child[tmp]; 35 } 36 tr[root].end=l; 37 } 38 int find(int x) 39 { 40 int root=0; 41 for(int i=31;i>=0;i--) 42 { 43 int tmp=(bool)((x&(1<<i))!=0); 44 tmp=tmp^1; 45 if(tr[root].child[tmp]) 46 root=tr[root].child[tmp]; 47 else 48 root=tr[root].child[1^tmp]; 49 } 50 return tr[root].end; 51 } 52 }trie; 53 int a[1000000]; 54 int main() 55 { 56 scanf("%d",&t); 57 for(int ccc=1;ccc<=t;ccc++) 58 { 59 printf("Case #%d:\n",ccc); 60 scanf("%d%d",&n,&m); 61 trie.dst(); 62 for(int i=1;i<=n;i++) 63 { 64 scanf("%d",&a[i]); 65 trie.insert(a[i],i); 66 } 67 for(int i=1;i<=m;i++) 68 { 69 int ask; 70 scanf("%d",&ask); 71 printf("%d\n",a[trie.find(ask)]); 72 } 73 } 74 return 0; 75 }