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

hdu 4825 Xor Sum(字典树)

时间:2015-07-17 09:52:02      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:hdu 4825 xor sum   字典树   

Xor Sum

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


Problem Description
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
 

题解:字典树,先把每个数分解成二进制,统一33位,再建成一颗字典树,插入后结尾记录该数的id。把要查询的数分解成二进制取反,在 字典树里找尽可能相同的数,
          即假如当前是1,如果该位字典树存在1,则顺着1找下去,否则找0,。

#include<cstring>
#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstdlib>
#define N 100010

using namespace std;

int n,k,m;
char s[40];
int a[N];

struct Trie {
    int id;
    struct Trie *Next[2];
    Trie() {
        id=0;
        for(int i=0; i<2; i++)
            Next[i]=NULL;
    }
};

void Trie_Inser(Trie *p,char s[],int id) {
    int i=0;
    Trie *q=p;
    while(i<=32) {
        int nx=s[i]-'0';
        if(q->Next[nx]==NULL) {
            q->Next[nx]=new Trie;
        }
        q=q->Next[nx];
        i++;
    }
    q->id=id;
}

int Trie_Serch(Trie *p,char s[]) {
    int i=0;
    Trie *q=p;
    while(i<=32) {
        int nx=s[i]-'0';
        if(q->Next[nx]==NULL)nx^=1;
        q=q->Next[nx];
        i++;
    }
    return q->id;
}

int main() {
   // freopen("test.in","r",stdin);
    int t;
    cin>>t;
    int ca=1;
    while(t--) {
        scanf("%d%d",&n,&m);
        int x;
        Trie *p=new Trie;
        for(int i=1; i<=n; i++) {
            scanf("%d",&x);
            a[i]=x;
            for(int i=0; i<40; i++)s[i]='0';
            int l=32;
            while(x) {
                if(x&1) {
                    s[l]='1';
                }
                x>>=1;
                l--;
            }
            Trie_Inser(p,s,i);
        }
        printf("Case #%d:\n",ca++);
        while(m--) {
            scanf("%d",&x);
            for(int i=0; i<40; i++)s[i]='1';
            int l=32;
            while(x) {
                if(x&1) {
                    s[l]='0';
                }
                x>>=1;
                l--;
            }
            int id=Trie_Serch(p,s);
            printf("%d\n",a[id]);
        }
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu 4825 Xor Sum(字典树)

标签:hdu 4825 xor sum   字典树   

原文地址:http://blog.csdn.net/acm_baihuzi/article/details/46919599

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