http://acm.hdu.edu.cn/showproblem.php?pid=4825
题意:
给出一些数,然后给出多个询问,每个询问要从之前给出的数中选择异或起来后值最大的数。
思路:
将给出的数建立01字典树,从高位开始建树。对于每个询问,如果当前位置值为0,那么在字典树中,如果有1的值,那么就优先走1,否则再走0。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 typedef long long ll; 6 7 int n, m; 8 9 struct Trie 10 { 11 Trie *son[2]; 12 ll ends; 13 Trie() 14 { 15 ends = 0; 16 memset(son,0,sizeof(son)); 17 } 18 }; 19 20 Trie *root, *s; 21 22 void insert(ll x) 23 { 24 s = root; 25 for(int i=32;i>=0;i--) 26 { 27 int c = ((x>>i)&1); 28 if(s->son[c] == 0) 29 s->son[c] = new Trie(); 30 s = s->son[c]; 31 } 32 s->ends = x; 33 } 34 35 ll query(ll x) 36 { 37 s = root; 38 for(int i=32;i>=0;i--) 39 { 40 int c = ((x>>i)&1); 41 if(s->son[c^1]) s = s->son[c^1]; 42 else s = s->son[c]; 43 } 44 return s->ends; 45 } 46 47 int main() 48 { 49 //freopen("in.txt","r",stdin); 50 int T; 51 scanf("%d",&T); 52 int kase = 0; 53 while(T--) 54 { 55 root = new Trie(); 56 scanf("%d%d",&n,&m); 57 for(int i=1;i<=n;i++) 58 { 59 int x; scanf("%d",&x); 60 insert(x); 61 } 62 printf("Case #%d: ",++kase); 63 while(m--) 64 { 65 int x; scanf("%d",&x); 66 printf("%lld ",query(x)); 67 } 68 } 69 return 0; 70 }