acwing143.最大异或对

原题链接:acwing143.最大异或对
算法:(Tire字典树)
思路:
1.由于时间与空间的限制我们显然不可能暴力得到答案,而且万一有重复的数字,我们没必要再用新的空间去储存,所以我们要利用原先已经用过的空间来储存
2.通过题目的异或我们很容易想到01,甚至二叉树,不如将每个数字转化为01比特串来用Tire树高效存储和查询
具体看代码实现

#include <bits/stdc++.h>
using namespace std;
 
const int N = 1e5+5;
//因为答案要最大,所以异或的时候要从30位开始,异或出最多1,答案自然最大了 
#define fir for (int k=30;k>=0;k--)	///Ai范围为正数int内,所以只要考虑30~0位,第31位为符号位,由题意都为正数,所以符号位都为0,最后答案异或出来都为正数,所以无需考虑第31位 
int tire[N*31][2];	//定义一个tire数,N==10^5,一个Ai拆分为一个01比特串,而且只考虑30~0位,所以节点最大个数乘以31就够了,每个节点的儿子节点只有两种可能0或者1,所以后面大小为2 
int idx;	//idx为0时,为根节点,也为空节点,其他节点从1开始计 

void insert(int x)
{
	int p=0;	//根节点开始走 
	fir
	{
		int u=x>>k&1;	//取出x在K位置的bit 
		if (!tire[p][u]) tire[p][u]=++idx;	//如果没有儿子节点,就创建一个儿子节点,注意是++idx 
		p=tire[p][u];	//往儿子节点走 
	}
}

int Search(int x)
{
	int p=0,res=0;
	fir
	{
		int u=x>>k&1;
		if (tire[p][u^1])	//一旦儿子节点里面有能异或出为1的,就异或走路 
		{
			p=tire[p][u^1];
			res|=1<<k;	//往res的K位置添加1 
		}
		else p=tire[p][u];	//不能异或出1,就走原先的路 
	}
	return res;	//得到x与原先储存好的所有数的异或最大值 
}
int main ()
{
	int n; cin>>n;
	int ans=0;
	while (n--)
	{
		int x; cin>>x;
		insert(x);
		ans=max(ans,Search(x));	//可以边插入边更新答案,因为每一次都能得到插入一个新的x之后的最大值 
	}
	cout<<ans;
	return 0;
} 
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值