【ybt高效进阶2-4-2】最大异或对

98 篇文章 1 订阅
9 篇文章 0 订阅

最大异或对

题目链接:ybt高效进阶2-4-2

题目大意

给你一堆数,小于二的三十一次方,问你要你选两个数,使它们异或的值更大。
要你输出这个最大异或值。

思路

我们考虑异或是干嘛的——就是在二进制中相同为 0 0 0,不同为 1 1 1

那我们要让异或值最大,就是要选出来的数最高位尽可能不同。
那我们可以用 Trie 树,让一个点有两个儿子,分别代表下一位是 0 0 0 还是 1 1 1

但这时候有个问题,我们是要根节点是最高位还是根节点是最低位呢?
我们想象一下,离根节点越近,它匹配的优先级就越高,那肯定就是越高位,就离根节点越近。
前面的位没有就补 0 0 0

那我们建树就弄好了,接着看看怎么查询某个数与前面的数匹配。
那首先从根节点下来就是从高位到低位,对于这一位,有不同的就选不同的,不然就看有没有相同的,如果都没有,那后面都是 0 0 0,就可以直接退了。
这个其实就是贪心。

当然如果有不同的才有对答案的贡献。

代码

#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;

struct Trie {
	int son[2], num;
}trie[3200001];
int n, a[100001], x, tmp[32], nn, now, KK, ans, zhi;

void build() {//插入
	now = 0;
	for (int i = 31; i >= 0; i--) {
		if (!trie[now].son[tmp[i]]) {
			trie[now].son[tmp[i]] = ++KK; 
		}
		now = trie[now].son[tmp[i]];
	}
	trie[now].num++;
}

void find() {
	now = 0;
	zhi = 0;
	for (int i = 31; i >= 0; i--) {
		if (!trie[now].son[tmp[i] ^ 1]) {//没有跟它这一位不同的
			if (trie[now].son[tmp[i]]) {//只有跟它着一位相同的
				now = trie[now].son[tmp[i]];
			}
			else break;//两个都没有,那后面的肯定是全都没有,不如退出
		}
		else {//有这一位不同的
			zhi += 1 << i;//加上这一位的贡献
			now = trie[now].son[tmp[i] ^ 1];
		}
	}
	ans = max(ans, zhi);//求出最大值
	return ;
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		x = a[i];
		nn = 0;
		memset(tmp, 0, sizeof(tmp));
		while (x) {
			if (x & 1) tmp[nn++] = 1;
				else tmp[nn++] = 0;
			x >>= 1;
		}
		
		find();
		build();
	}
	
	printf("%d", ans);
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值