CSUOJ 1216 异或最大值 (01Trie)

129 篇文章 0 订阅
78 篇文章 0 订阅

1216: 异或最大值

Time Limit: 2 Sec   Memory Limit: 128 MB
Submit: 367   Solved: 118
[ Submit][ Status][ Web Board]

Description

给定一些数,求这些数中两个数的异或值最大的那个值

Input

第一行为数字个数n,1 <= n <= 10 ^ 5。接下来n行每行一个32位有符号非负整数。

Output

任意两数最大异或值

Sample Input

3
3
7
9

Sample Output

14

题目分析:把每个数的二进制表示插入一颗Trie,插得时候从高位开始,这个想想就知道,然后搜的时候直接贪心,复杂度O(n)

#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int const MAX = 4e6;
int n;

struct Trie
{
	int root, tot, next[MAX][2], end[MAX];
	inline int Newnode()
	{
		memset(next[tot], -1, sizeof(next[tot]));
		end[tot] = 0;
		return tot ++;
	}

	inline void Init()
	{
		tot = 0;
		root = Newnode();
	}

	inline void Insert(ll x)
	{
		int p = root;
		for(int i = 31; i >= 0; i--)
		{
			int idx = ((1 << i) & x) ? 1 : 0;
			if(next[p][idx] == -1)
				next[p][idx] = Newnode();
			p = next[p][idx];
		}
		end[p] = x;
	}

	inline int Search(int x)
	{
		int p = root;
		for(int i = 31; i >= 0; i--)
		{
			int idx = ((1 << i) & x) ? 1 : 0;
			if(idx == 0)
				p = next[p][1] != -1 ? next[p][1] : next[p][0];
			else
				p = next[p][0] != -1 ? next[p][0] : next[p][1];
		}
		return x ^ end[p];
	}

}tr;

int main()
{
	while(scanf("%d", &n) != EOF)
	{
		int ma = 0, x;
		tr.Init();
		for(int i = 0; i < n; i++)
		{
			scanf("%d", &x);
			tr.Insert(x);
			ma = max(ma, tr.Search(x));
		}
		printf("%d\n", ma);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值