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:\n", cas); 66 for(int i = 1; i <= m; i++) { 67 long long q; 68 scanf("%d", &q); 69 printf("%d\n", a[trie.Query(q)]); 70 } 71 } 72 return 0; 73 }
时间: 2024-10-27 11:32:31