HDU-4825 Xor Sum (Dictionary tree difference or max)

Topic link: click here

My github address: click here

Problem Description
Zeus and Prometheus played 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
 
The meaning of the question: It is to ask n numbers with you, and then ask m times, each time you ask a number k, find the number with the largest XOR value of k among the n numbers
 
In general traversal, it is definitely easy to T
So we can build a dictionary tree, each branch is 0, or 1
 
 
/*
    data:2018.04.26
    author:gswycf
    link:http://acm.hdu.edu.cn/showproblem.php?pid=4825
    accout:tonysave
*/
#define ll long long
#define IO ios::sync_with_stdio(false);
#define maxn 100005

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<vector>
using namespace std;
class Node
{
    public:
        int a[2];
        ll v;
};
Node node[32*maxn];int cnt=0;
void init()
{
    cnt=0;
    memset(node,0,sizeof(node));
}
void update(ll num)
{
    int p=0;
    for(int i=32;i>=0;i--)
    {
        int c=((num>>i)&1);
        if(!node[p].a[c])
            node[p].a[c]=++cnt;
        p=node[p].a[c];
    }
    node[p].v=num;
}
ll query(ll num)
{
    int p=0;
    for(int i=32;i>=0;i--)
    {
        int c=((num>>i)&1);
        if(node[p].a[(c^1)])p=node[p].a[(c^1)];
        else p=node[p].a[c];
    }
    return node[p].v;
}
intmain ()
{
    int ca,n,m;ll tem;
    while(~scanf("%d",&ca))
    {
        for(int i=1;i<=ca;i++)
        {
            init();
            scanf("%d%d",&n,&m);
            for(int j=1;j<=n;j++)
            {
                scanf("%lld",&tem);
                update(tem);
            }
            printf("Case #%d:\n",i);
            for(int j=1;j<=m;j++)
            {
                scanf("%lld",&tem);
                printf("%lld\n",query(tem));
            }
        }
    }
}

A few things to note:

(1) Use ll, because there will be problems with int shifting right by 32 bits

(2) The init() function needs to be called for each case

(ps: because of these two errors, stuck for an hour, ORZ...)

 

Guess you like

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