码迷,mamicode.com
首页 > 其他好文 > 详细

HDU - 4825 Xor Sum

时间:2018-04-01 00:03:21      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:new   如何   数据   需要   back   long   col   scan   cst   

Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么? 

Input

输入包含若干组测试数据,每组测试数据包含若干行。 
输入的第一行是一个整数T(T < 10),表示共有T组数据。 
每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。Output对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。 
对于每个询问,输出一个正整数K,使得K与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 

题目链接

分析
首先得清楚,什么时候才求得最大的异或和?就是从高位开始,尽量让每个位不同,这样异或的结果一定最大。所以问题就是如何把所有数的二进制
表示保存起来,并需要便于访问查找。数最大是2^32,我们可以使用一个树来存,也就是字典树啦,以高位为根。在查找时,尽量选取不同数值的路径。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include <queue>
#include <vector>
#include<bitset>
#include<map>
#include<deque>
using namespace std;
typedef long long LL;
const int maxn = 1e5+5;
const int mod = 77200211+233;
typedef pair<int,int> pii;
#define X first
#define Y second
#define pb push_back
//#define mp make_pair
#define ms(a,b) memset(a,b,sizeof(a))
const int inf = 0x3f3f3f3f;
#define lson l,m,2*rt
#define rson m+1,r,2*rt+1


struct node{
    int num;
    node *son[2];
    node(){
        num=0;
        son[0]=son[1]=NULL;
    }
};

node *root;

void Insert(int x){
    int a[32];
    int xx=x;
    node *p=root,*q;
    for(int i=0;i<32;i++){
        a[i]=xx&1;
        xx>>=1;
    }
    for(int i=31;i>=0;i--){
        if(p->son[a[i]]!=NULL){
            p=p->son[a[i]];
        }else{
            q = new node;
            p->son[a[i]]=q;
            p=q;
        }
    }
    p->num=x;
}

int Find(int x){
    int a[32];

    node *p=root;
    for(int i=0;i<32;i++){
        a[i]=x&1;
        x>>=1;
    }

    for(int i=31;i>=0;i--){
        if(p->son[!a[i]]!=NULL){
            p=p->son[!a[i]];
        }else p=p->son[a[i]];
    }
    return p->num;
}

void del(node *p){
    for(int i=0;i<2;i++)
        if(p->son[i]!=NULL) del(p->son[i]);

    delete(p);
}

int main(){
    int t;
    scanf("%d",&t);
    int cas=0;
    while(t--){
        root = new node;
        int n,m;
        scanf("%d%d",&n,&m);
        int x;
        for(int i=0;i<n;i++){
            scanf("%d",&x);
            Insert(x);
        }
        printf("Case #%d:\n",++cas);
        while(m--){
            scanf("%d",&x);
            printf("%d\n",Find(x));
        }
        del(root);
    }
    return 0;
}

 

 

HDU - 4825 Xor Sum

标签:new   如何   数据   需要   back   long   col   scan   cst   

原文地址:https://www.cnblogs.com/fht-litost/p/8684608.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!