HDU4825:Xor Sum——题解

http://acm.hdu.edu.cn/showproblem.php?pid=4825

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

板子题。

看到异或想到把数拆成二进制,从高位到低位存在Trie树中。

然后对于每次询问的s同样拆成二进制,在Trie树上跑,显然对于高位越是1越好,所以我们尽可能让这位的两个数不一样。

换句话说s的第i位要和k的第i位尽可能不同(当然如果没有选择也只能走相同的了)

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
const int N=1e5+5;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct node{
    int son[2],id;
}tr[33*N];
int tot,a[N];
void insert(int x,int id){
    int now=1;
    for(int i=31;i>=0;i--){
    bool l=x&(1<<i);
    if(!tr[now].son[l])tr[now].son[l]=++tot;
    now=tr[now].son[l];
    }
    tr[now].id=id;
    return;
}
inline void init(){
    memset(tr,0,sizeof(tr));
    tot=1;
}
int main(){
    int t=read();
    for(int test=1;test<=t;test++){
    printf("Case #%d:\n",test);
    init();
    int n=read(),m=read();
    for(int i=1;i<=n;i++)insert(a[i]=read(),i);
    for(int i=1;i<=m;i++){
        int x=read(),now=1;
        for(int j=31;j>=0;j--){
        bool op=x&(1<<j);
        if(tr[now].son[op^1])now=tr[now].son[op^1];
        else now=tr[now].son[op];
        }
        printf("%d\n",a[tr[now].id]);
    }
    }
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

 +本文作者:luyouqi233。               +

 +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2018-03-07 20:16  luyouqi233  阅读(585)  评论(0编辑  收藏  举报