CSU1216 异或最大值(字典树)

CSU1216 异或最大值

Description

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

Input

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

Output

任意两数最大异或值

Sample Input

3
3
7
9

Sample Output

14

题解

题意

中文题面,求一组数据中的异或最大值。

思路

建立字典树,在查找过程时,每次选择尽可能远的数值,也就是说尽可能和当前位不相同。

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const int MAXN = 4e6+10;
int n;
 
struct Trie
{
	int sz, ch[MAXN][2], val[MAXN];
	
	void init(){
		sz = 1;
		memset(ch,-1,sizeof(ch));
		memset(val,0,sizeof(val));
	}
 
	void insert(int x){
		int u = 0;
		for(int i = 31; i >= 0; i--){
			int c = ((1 << i) & x) ? 1 : 0;
			if(ch[u][c] == -1){
				memset(ch[sz], -1, sizeof(ch[sz]));
				ch[u][c] = sz;
				sz++;
			}
			u = ch[u][c];
		}
		val[u] = x;
	}
 
	int search(int x){
		int u = 0;
		for(int i = 31; i >= 0; i--){
			int c = ((1 << i) & x) ? 1 : 0;
			if(c == 0)
				u = ch[u][1] != -1 ? ch[u][1] : ch[u][0];
			else
				u = ch[u][0] != -1 ? ch[u][0] : ch[u][1];
		}
		return x ^ val[u];
	}
 
};
Trie tree;
int main(){
	while(~scanf("%d", &n)){
		tree.init();
		int mmax = 0, x;
		for(int i = 0; i < n; i++){
			scanf("%d", &x);
			tree.insert(x);
			mmax = max(mmax, tree.search(x));
		}
		printf("%d\n", mmax);
	}
}
posted @ 2018-08-11 15:57  caomp  阅读(502)  评论(0)    收藏  举报