HDOJ 4825 Xor Sum

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4825

题意:给出n个数,再给你m个数,问这m个数中分别能在这个n个数中找到能使这两个数的异或值最大的那个数。

暴力肯定爆时间,毫无疑问。

所以这道题我们要考虑建立字典树进行贪心来处理,很明显异或运算找最大值是要从高位开始,找有没有与目标数相应位置上不同的值,能找到就取,找不到就不取,这样从高位下来肯定是能达到最大值的,关于怎么从最高位开始找,我们就要借助字典树进行处理。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL __int64
using namespace std;
const int maxn = 1000000+2;
int tree[maxn<<2][2],cnt[maxn<<2],tot;
LL a[maxn];
void insertTrie(LL num,int id)
{
	int now = 0;
	for(int i=32; i>=0; i--)
	{
		int w = (num&(1LL<<i)) > 0;
		if(tree[now][w] == 0)
		{
			tree[now][w] = ++tot;
			memset(tree[tot],0,sizeof(tree[tot]));
			cnt[tot] = 0;
		}
		now = tree[now][w];
	}
	cnt[now] = id;
}
int searchTrie(LL num)
{
	int now = 0;
	for(int i=32; i>=0; i--)
	{
		int w = (num&(1LL<<i)) > 0;
		if(tree[now][!w]) now = tree[now][!w];
		else now = tree[now][w];
	}
	return cnt[now];
}
int main()
{
	int T,t=0;
	scanf("%d",&T);
	while(T--)
	{
		memset(tree[0],0,sizeof(tree[0]));
		tot = 0;
		printf("Case #%d:\n",++t);
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i=1; i<=n; i++)
		{
			scanf("%I64d",&a[i]);
			insertTrie(a[i],i);
		}
		for(int i=0; i<m; i++)
		{
			LL s;
			scanf("%I64d",&s);
			printf("%I64d\n",a[searchTrie(s)]);
		}
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值