题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4825
题目:
题意:
先给你n个数,再进行q次查询,每次查询数s与原来给的n个数异或和最大的数。
思路:
建一棵字典树,将n个数转换成二进制存进去,每次查询时,对s的每一位进行匹配(从高位开始匹配,毕竟你低位再大也没有一位高位大效果好,如34 <42),匹配第i位时为了值尽可能大应先匹配1-a[i]再匹配a[i]。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <ctime> 5 #include <stack> 6 #include <cmath> 7 #include <queue> 8 #include <string> 9 #include <cstdio> 10 #include <vector> 11 #include <iomanip> 12 #include <cstring> 13 #include <iostream> 14 #include <algorithm> 15 using namespace std; 16 17 typedef long long LL; 18 typedef pair<LL, LL> pll; 19 typedef pair<LL, int> pli; 20 typedef pair<int, int> pii; 21 typedef unsigned long long uLL; 22 23 #define lson rt<<1 24 #define rson rt<<1|1 25 #define name2str(name)(#name) 26 #define bug printf("**********\n"); 27 #define IO ios::sync_with_stdio(false); 28 #define debug(x) cout<<#x<<"=["<<x<<"]"<<endl; 29 #define FIN freopen("/home/dillonh/CLionProjects/in.txt","r",stdin); 30 31 const double eps = 1e-8; 32 const int maxn = 1e5 + 7; 33 const int inf = 0x3f3f3f3f; 34 const double pi = acos(-1.0); 35 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 36 37 int t, n, q, le, root; 38 LL x; 39 int a[35]; 40 41 struct node{ 42 int cnt; 43 int nxt[3]; 44 45 void init(){ 46 cnt = 0; 47 nxt[0] = nxt[1] = -1; 48 } 49 }T[maxn*55]; 50 51 void insert(LL n){ 52 int now = root; 53 for(int i = 0; i <= 32; i++) { 54 a[i] = n % 2; 55 n /= 2; 56 } 57 for(int i = 32; i >= 0; i--){ 58 int x = a[i]; 59 if(T[now].nxt[x] == -1){ 60 T[le].init(); 61 T[now].nxt[x] = le++; 62 } 63 now = T[now].nxt[x]; 64 T[now].cnt++; 65 } 66 } 67 68 LL search(LL n){ 69 int now = root; 70 LL ans = 0; 71 for(int i = 0; i <= 32; i++) { 72 a[i] = n % 2; 73 n /= 2; 74 } 75 for(int i = 32; i >= 0; i--){ 76 int x = a[i]; 77 if(T[now].nxt[1 - x] != -1) { 78 if(x == 0) ans += 1LL << i; 79 now = T[now].nxt[1-x]; 80 } else { 81 if(x == 1) ans += 1LL << i; 82 now = T[now].nxt[x]; 83 } 84 } 85 return ans; 86 } 87 88 int main() { 89 int icase = 0; 90 scanf("%d", &t); 91 while(t--) { 92 le = 1; 93 T[0].init(); 94 scanf("%d%d", &n, &q); 95 for(int i = 1; i <= n; i++) { 96 scanf("%lld", &x); 97 insert(x); 98 } 99 printf("Case #%d:\n", ++icase); 100 for(int i = 1; i <= q; i++) { 101 scanf("%lld", &x); 102 printf("%lld\n", search(x)); 103 } 104 } 105 return 0; 106 }
原文地址:https://www.cnblogs.com/Dillonh/p/9752029.html
时间: 2024-11-09 02:58:45