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

题意:

给出n个数a[],然后给出m个问题Y,求a[]里面的X,有X xor Y最大。

字典树的作用之一----最大异或:

如果找一个数的最大异或,当然需要从高位到低位(已转化为二进制),尽可能不同。

  • 那么我们从高位到低位表示一个数X,并且存入字典树中,结尾节点记录X(不同的数结尾肯定不同)。
  • 对于询问,从高位到地位先尽可能从兄弟边走。

这可Trie树高度为32,复杂度在接受范围内。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=;
inline int read()
{
int res=;char x=getchar();while(x<''||x>'') x=getchar();
while(x>=''&&x<=''){ res=res*+x-'';x=getchar();}return res;
}
int q_pow(int a,int x){ int res=;while(x){ if(x&) res*=a; x>>=; a=a*a;} return res; }
struct TREE
{
int ch[maxn][],cnt,num[maxn];
void init() { memset(ch,,sizeof(ch));cnt=;}
void insert(int s[],int val)
{
int Now=;
for(int i=;i>=;i--){
if(!ch[Now][s[i]]) ch[Now][s[i]]=++cnt;
Now=ch[Now][s[i]];
} num[Now]=val;
}
int query(int s[])
{
int Now=;
for(int i=;i>=;i--){
if(ch[Now][s[i]^]) Now=ch[Now][s[i]^];
else Now=ch[Now][s[i]];
} return num[Now];
}
}Tree;
int main()
{
int T,n,m,x,tx,a[],Case=;
scanf("%d",&T);
while(T--){
printf("Case #%d:\n",++Case);
scanf("%d%d",&n,&m);
Tree.init();
for(int i=;i<=n;i++){
scanf("%d",&x);tx=x;
for(int j=;j<=;j++) {
a[j]=x%; x>>=;
} Tree.insert(a,tx);
}
for(int i=;i<=m;i++) {
scanf("%d",&x);
for(int j=;j<=;j++) {
a[j]=x%; x>>=;
} printf("%d\n",Tree.query(a));
}
}return ;
}

兄弟题目:Find MaxXorSum ,这个题求最大异或结果。

所以不需要记录来自于那个数字,记录下和即可。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=;
inline int read()
{
int res=;char x=getchar();while(x<''||x>'') x=getchar();
while(x>=''&&x<=''){ res=res*+x-'';x=getchar();}return res;
}
int q_pow(int a,int x){ int res=;while(x){ if(x&) res*=a; x>>=; a=a*a;} return res; }
struct TREE
{
int ch[maxn][],cnt;
void init() { memset(ch,,sizeof(ch));cnt=;}
void insert(int s[])
{
int Now=;
for(int i=;i>=;i--){
if(!ch[Now][s[i]]) ch[Now][s[i]]=++cnt;
Now=ch[Now][s[i]];
}
}
int query(int s[])
{
int Now=,res=;
for(int i=;i>=;i--){
if(ch[Now][s[i]^]) Now=ch[Now][s[i]^],res+=q_pow(,i);
else if(ch[Now][s[i]]) Now=ch[Now][s[i]];
else break;
} return res;
}
}Tree;
int main()
{
int T,n,i,j,a[],b[],tmp,ans;
scanf("%d",&T);
while(T--){
Tree.init(); ans=; scanf("%d",&n);
for(i=;i<=n;i++){
scanf("%d",&a[i]); tmp=a[i];
for(j=;j<=;j++) {
b[j]=tmp%; tmp>>=;
} Tree.insert(b);
}
for(i=;i<=n;i++) {
for(j=;j<=;j++) {
b[j]=a[i]%; a[i]>>=;
} ans=max(ans,Tree.query(b));
} printf("%d\n",ans);
}return ;
}

HDU4825 Xor Sum(字典树解决最大异或问题)的更多相关文章

  1. HDU--4825 Xor Sum (字典树)

    题目链接:HDU--4825 Xor Sum mmp sb字典树因为数组开的不够大一直wa 不是报的 re!!! 找了一下午bug 草 把每个数转化成二进制存字典树里面 然后尽量取与x这个位置上不相同 ...

  2. HDU4825 Xor Sum —— Trie树

    题目链接:https://vjudge.net/problem/HDU-4825 Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Li ...

  3. 2014百度之星第三题Xor Sum(字典树+异或运算)

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total ...

  4. HDU 4825 Xor Sum 字典树+位运算

    点击打开链接 Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) ...

  5. hdu 4825 xor sum(字典树+位运算)

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total S ...

  6. AcWing:143. 最大异或对(01字典树 + 位运算 + 异或性质)

    在给定的N个整数A1,A2……ANA1,A2……AN中选出两个进行xor(异或)运算,得到的结果最大是多少? 输入格式 第一行输入一个整数N. 第二行输入N个整数A1A1-ANAN. 输出格式 输出一 ...

  7. HDU-4825 Xor Sum,字典树好题!

    Xor Sum 一遍A了之后大呼一声好(keng)题!debug了两小时~~~~百度之星资格赛,可以. 题意:给你一个n个元素的数组,m次查询,每次输入一个数k要求从数组中找到一个数与k异或值最大,输 ...

  8. ☆ [HDU4825] Xor Sum「最大异或和(Trie树)」

    传送门:>Here< 题意:给出一个集合,包含N个数,每次询问给出一个数x,问x与集合中的一个数y异或得到最大值时,y是多少? 解题思路 由于N,M非常大,暴力显然不行.抓住重点是异或,所 ...

  9. [Hdu4825]Xor Sum(01字典树)

    Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问 ...

随机推荐

  1. linux下添加自动启动项,linux 开机自动启动脚本方法

    #service servicename status是当前状态#chkconfig --list servicename是查看启动状态,也就是是否开机自动启动 首先写好脚本,如 mysql,把它放到 ...

  2. https双向认证訪问管理后台,採用USBKEY进行系统訪问的身份鉴别,KEY的证书长度大于128位,使用USBKEY登录

    近期项目需求,须要实现用USBKEY识别用户登录,採用https双向认证訪问管理后台管理界面,期间碰到过一些小问题,写出来给大家參考下. 1:前期准备工作 USBKEY 硬件:我买的是飞天诚信 epa ...

  3. windows下redis安装以及简单配置

    1.下载redis 下载地址https://github.com/dmajkic/redis/downloads.有32bit和64bit根据自己需要选择就可以了. 2.安装redis 首先使用cmd ...

  4. SpringBoot学习之@Controller和@RestController

    今天我们来研究一下@Controller和@RestController的用法 @Controller 1.Controller可以用来跳转页面,并且必须配合模板来使用. @Controller // ...

  5. Regex 手机号 座机 正則表達式

    近期在工作中须要推断一个号码是否是手机号,是否是座机号. 在网上也搜到了大家总结的方法,没有直接使用这些方法是由于:手机号码在不断開始新的号码段(比方17x).座机号中个别区号由于行政区域的变化而废除 ...

  6. PADS的历史版本

    1986年:PADS PCB,DOS操作系统 1989年:PADS Logic,DOS操作系统 1990年:PADS 2000,DOS操作系统 1993年:PADS Perform,DOS和Windo ...

  7. Long-term stable release maintenance

    http://en.wikipedia.org/wiki/Linux_kernel 2014.5.28 2.6.32 2 December 2009[122] 2.6.32.62[123] Willy ...

  8. git clean

    使用git clean清除未加入版控的数据 作者:Level Up  发布日期:2012-12-21 10:48:10       笔者在使用版本控制软件时,不知为何常常会有些暂存的数据产生.像是下面 ...

  9. maven命令学习-发布上传jar包-deploy

    Maven学习六之利用mvn deploy命令上传包 转http://blog.csdn.net/woshixuye/article/details/8133050 mvn:deploy在整合或者发布 ...

  10. 代写GIS系统

    代写GIS系统,熟悉arcgis,leaflet ,百度地图等api.可以提供系统代写,技术咨询等