CSUOJ 1216 异或最大值 (01Trie)

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
题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1216

题目分析:把每个数的二进制表示插入一颗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);
	}
}


你可能感兴趣的:(csuoj,01Trie)