Xor Sum(HDU4825 + 字典树)

题目链接:

  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 }

猜你喜欢

转载自www.cnblogs.com/Dillonh/p/9752029.html