HDU - 4825 Xor Sum (01 dictionary tree)

Xor Sum

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 4040    Accepted Submission(s): 1760


Problem Description
Zeus and Prometheus made a game, Prometheus gave Zeus a set, the set contains N positive integers, and then Prometheus will send M times to Zeus, each query contains a positive integer S, then Zeus needs to find in the set. Get a positive integer K that maximizes the XOR result of K and S. In order to let Zeus see the greatness of mankind, Prometheus immediately agreed that Zeus could turn to mankind for help. Can you prove human wisdom?
 

Input
The input contains sets of test data, each set of test data contains several rows.
The first line of input is an integer T (T < 10), representing a total of T groups of data.
The first line of each set of data inputs two positive integers N, M (<1=N, M<=100000), the next line contains N positive integers, representing Zeus's obtained set, and then M lines, each line A positive integer S, representing the positive integer that Prometheus is asking. All positive integers do not exceed 2^32.
 

Output
For each group of data, first need to output a separate line of "Case #?:", where the question mark should be filled with the current number of data groups, and the number of groups starts from 1.
For each query, output a positive integer K that maximizes the XOR value of K and S.
 

Sample Input
 
  
2 3 2 3 4 5 1 5 4 1 4 6 5 6 3
 

Sample Output
 
  
Case #1: 4 3 Case #2: 4
 

Source
 

Recommend
liuyiding
 


Problem-solving ideas: adopt greedy thinking, from the highest position, constantly take the inverse of S. So you can build a dictionary tree for query. Used to save templates.


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;

int node[100000*20][2];
int tot = 0;
int root=0;

void insert(ll x){
    int cur=root;
    for(int i=32;i>=0;i--){
        int c=((x>>i)&1);
        if(node[cur][c]==0)
            node[cur][c]=++tot;
        cur=node[cur][c];
    }
}

ll search(ll x){
    int cur=root;
    bitset<33> ans;
    for(int i=32;i>=0;i--){
        int c=((x>>i)&1);
        if(c){
            if(node[cur][0]){
                ans[i]=0;
                cur=node[cur][0];
            }
            else{
                ans[i]=1;
                cur=node[cur][1];
            }
        }
        else{
            if(node[cur][1]){
                ans[i]=1;
                cur=node[cur][1];
            }
            else{
                cur=node[cur][0];
            }
        }
    }
    return ans.to_ullong();
}

int main(){

    int T;
    scanf("%d",&T);
    for(int qqq=1;qqq<=T;qqq++){
        printf("Case #%d:\n",qqq);
        to=0;
        memset(node,0,sizeof(node));
        int N,M;
        ll x;
        scanf("%d%d",&N,&M);
        for(int i=0;i<N;i++){
            scanf("%lld",&x);
            insert(x);
        }
        while(M--){
            scanf("%lld",&x);
            cout<<search(x)<<endl;
        }
    }
    return 0;
}
















Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325900001&siteId=291194637