1012 - trie树最大异或值 - The XOR Largest Pair

描述

在给定的N个整数A1,A2……AN中选出两个进行xor运算,得到的结果最大是多少?

输入格式

第一行一个整数N,第二行N个整数A1~AN。

输出格式

一个整数表示答案。

样例输入

3
1 2 3

样例输出

3

数据范围与约定

  • 对于100%的数据: N<=10^5, 0<=Ai<2^31。

 

分析

数组开小了……,你要这样想:一个数最多开31个节点,有1e5个数,就开 31*10^5就差不多了

根据异或的性质:我们可以知道若两个位置值相异则取1,相同则取0

那我们需要最大的异或值,肯定希望每一位都尽量不同啊,那就可以在trie树上走了

对于每一个 ai 我们在trie树上每一步都试图往与当前位相反的字符指针走,如果没有的话就只能走相同位咯

但具体实现的时候,可以稍微优化一下下,每加入一个数,先在之前的trie树上走一遍,然后再将这个数插入trie树,每次都这样搞,就会避免很多重复的情况了

 

代码

#include<bits/stdc++.h>
#define N 100009
#define ll long long
using namespace std;
int a,n,trie[9000000][2],tot=0;//数组啊!!!!!!
void insert(int x){
	int pos=0;
	for(int i=31;i>=0;--i){
		int c;
		if(x&(1ll<<i)) c=1;
		else c=0;
		if(!trie[pos][c]) trie[pos][c]=++tot;
		pos=trie[pos][c];
	}
}
ll query(int x){
	int pos=0;
	ll res=0;
	for(int i=31;i>=0;--i){
		int c;
		if(x&(1ll<<i)) c=1;
		else c=0;
		if(trie[pos][c^1]) pos=trie[pos][c^1],res=res|(1ll<<i);
		else pos=trie[pos][c];
	}
	return res;
}
int main(){
	scanf("%d",&n);
	int i,j,k;
	ll maxn=-1;
	for(i=1;i<=n;++i){
		scanf("%d",&a);
		maxn=max(maxn,query(a));
		insert(a);
	} 
	printf("%lld",maxn);
	return 0;
}

 

    原文作者:Trie树
    原文地址: https://blog.csdn.net/weixin_42557561/article/details/83033453
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞