首页 > 编程语言 > 详细

【算法竞赛进阶指南】字典树 The XOR Largest Pair

时间:2020-11-03 10:17:48      阅读:34      评论:0      收藏:0      [点我收藏+]

题目链接

题意

给出 N 个数字,任意选择两个数字进行异或运算,求结果最大值。

思路

我们对于每个数字求与其异或得到的最大值,求这 N 个最大值的最大值。

把每个数字看做一个长度为 32 的二进制串,将其翻转,更新到 trie 中。

对于每个二进制串 \(S\),遍历其值 \(S_i\)
在 trie 中每次都尝试向下访问与 \(S_i\) 相反的字符。
如果能向下访问那么向下访问,当前数字增加 \(1LL<<(31-i)\) ( 字符下标从 0 开始),
否则向下访问与当前字符相同的节点。

代码

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll N=2e6+10;

ll arr[N];
int tot=1,trie[N][2];
ll s[N];
void insert()
{
	ll p=1;
	for(ll i=0;i<32;i++){
		ll now=s[i];
		if(!trie[p][now]){
			trie[p][now]=++tot;
		}
		p=trie[p][now];
	}
}

ll solve()
{
	ll rel=0,p=1,cnt=31;
	for(ll i=0;i<32;i++,cnt--){
		ll now=1^s[i];
		if(trie[p][now]){
			rel+=(1LL<<cnt);
		}else{
			now=s[i];
		}
		p=trie[p][now];
	}	
	return rel;
}

int main()
{
	ll n,rel=0;
	scanf("%lld",&n);
	for(ll i=1;i<=n;i++){
		scanf("%lld",&arr[i]);
		for(ll j=0;j<32;j++){
			s[31-j]=(arr[i]&(1LL<<j))?1:0;
		}
		insert();
		rel=max(rel,solve());
	}
	printf("%lld\n",rel);
	return 0;
}

【算法竞赛进阶指南】字典树 The XOR Largest Pair

原文:https://www.cnblogs.com/valk3/p/13917929.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!