HDU 4825:Xor Sum(Trie)

http://acm.hdu.edu.cn/showproblem.php?pid=4825

题意:给出N个数,M个询问,每个询问给出一个X,问在这N个数中哪个数和X异或后结果最大。

思路:可以用Trie构造出sigmaSize为0和1的点,先将N个数插入Trie,然后询问在Trie上尽量找可以不同的数,不同的话异或起来是最大的。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <string>
 6 #include <cmath>
 7 #include <queue>
 8 #include <vector>
 9 using namespace std;
10 #define N 2000010
11 int a[100005];
12 struct Trie
13 {
14     int ch[N][2], num; //注意节点数要开大,因为每个N可能有很多个节点
15     int val[N];
16     void init()
17     {
18         num = 1;
19         memset(ch[0], 0, sizeof(ch[0]));
20     }
21 
22     void Update(int x, int id)
23     {
24         int u = 0;
25         for(int i = 31; i >= 0; i--) {
26             int v = ((1 << i) & x) > 0 ? 1 : 0;
27             if(!ch[u][v]) {
28                 memset(ch[num], 0, sizeof(ch[num]));
29                 val[num] = 0;
30                 ch[u][v] = num++;
31             }
32             u = ch[u][v];
33         }
34         val[u] = id;
35     }
36 
37     int Query(int x)
38     {
39         int u = 0;
40         for(int i = 31; i >= 0; i--) {
41             int v = ((1 << i) & x) > 0 ? 1 : 0;
42             v = !v;
43             if(ch[u][v]) {
44                 u = ch[u][v];
45             } else{
46                 u = ch[u][!v];
47             }
48         }
49         return val[u];
50     }
51 }trie;
52 
53 int main()
54 {
55     int t;
56     scanf("%d", &t);
57     for(int cas = 1; cas <= t; cas++) {
58         int n, m;
59         scanf("%d%d", &n, &m);
60         trie.init();
61         for(int i = 1; i <= n; i++) {
62             scanf("%d", &a[i]);
63             trie.Update(a[i], i);
64         }
65         printf("Case #%d:
", cas);
66         for(int i = 1; i <= m; i++) {
67             long long q;
68             scanf("%d", &q);
69             printf("%d
", a[trie.Query(q)]);
70         }
71     }
72     return 0;
73 }
原文地址:https://www.cnblogs.com/fightfordream/p/5911226.html