nyoj 947 Max Xor(字典树)

Max Xor

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 4
描述
给一个长度为 n 的数列 {an} ,找出 max {ai ^ aj}。
输入
多组测试数据。
第 1 行 1 个数 n。(1<=n<=10^5)
接下来的 1 行有 n 个数 ai。(0<=ai<=10^12)
输出
1 行有 1 个数,max {ai ^ aj}。
样例输入
3
0 1 2
样例输出
3


解题思路:这道题很巧妙,首先把数字变成01串,这个很容易想到,但关键是如何处理这些01串,使得其xor最大。这里采用了字典树,将所有01串都放在字典树上,然后通过字典树的匹配去寻找最大的xor值。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;

typedef long long LL;
const int maxn = 100005;
struct Node
{
	Node *next[2];
};
int n,c[55];
LL a[maxn];
Node *root;

void process(LL s)
{
	int num = 50;
	memset(c,0,sizeof(c));
	while(s)
	{
		c[num--] = s % 2;
		s /= 2;
	}
}

void insert(LL s)
{
	process(s);
	Node *p = root;
	for(int i = 0; i <= 50; i++)
	{
		if(p->next[c[i]] == NULL)
		{
			p->next[c[i]] = (Node *)malloc(sizeof(Node));
			p->next[c[i]]->next[0] = NULL;
			p->next[c[i]]->next[1] = NULL;
		}
		p = p->next[c[i]];
	}
}

LL find(LL s)
{
	process(s);
	Node *p = root;
	LL sum = 0;
	for(int i = 0; i <= 50; i++)
	{
		if(p->next[!c[i]] == NULL)
		{
			sum = sum * 2;
			p = p->next[c[i]];
		}
		else 
		{
			sum = sum * 2 + 1;
			p = p->next[!c[i]];
		}
	}
	return sum;
}

int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		for(int i = 1; i <= n; i++)
			scanf("%lld",&a[i]);
		root = (Node *)malloc(sizeof(Node));
		root->next[0] = root->next[1] = NULL;
		for(int i = 1; i <= n; i++)
			insert(a[i]);
		LL ans = 0;
		for(int i = 1; i <= n; i++)
			ans = max(ans,find(a[i]));
		printf("%lld\n",ans);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值