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/+
+++++++++++++++++++++++++++++++++++++++++++