LOJ10050 The XOR Largest Pair

题意

在给定的 \(N\) 个整数 \(A_1,A_2,…,A_N\) 中选出两个进行异或运算,得到的结果最大是多少?

对于 \(100\%\) 的数据,\(1\le N\le 10^5, 0\le A_i <2^{31}\)

分析

参照jklover的题解。

使用 Trie 树,将每个数看做一个长度为 32 的字符串插入 Trie 树中.

每次插入前贪心找异或最大值即可。

时间复杂度:线性。

代码

询问的时候,要保证至少插入了一个,须要先插入后后询问。这份代码按道理就是错的,ans在进行第一次find的被赋成了x。

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read()
{
	rg T data=0,w=1;
	rg char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') w=-1;
		ch=getchar();
	}
	while(isdigit(ch))
	{
		data=data*10+ch-'0';
		ch=getchar();
	}
	return data*w;
}
template<class T>il T read(rg T&x)
{
	return x=read<T>();
}
typedef long long ll;

co int N=32e5+1;
int bin[33],tot;
int son[N][2];

void turn(int n)
{
	std::fill(bin+1,bin+33,0);
	for(int i=1;i<=32;++i,n>>=1)
		bin[i]=n&1;
}

int find()
{
	int u=0,res=0;
	for(int i=32;i>=1;--i)
	{
		if(son[u][bin[i]^1])
		{
			u=son[u][bin[i]^1];
			res+=(1<<(i-1));
		}
		else
			u=son[u][bin[i]];
	}
	return res;
}

void insert()
{
	int u=0;
	for(int i=32;i>=1;--i)
	{
		if(!son[u][bin[i]])
			son[u][bin[i]]=++tot;
		u=son[u][bin[i]];
	}
}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	int n=read<int>(),ans=0;
	while(n--)
	{
		int x=read<int>();
		turn(x);
		ans=std::max(ans,find());
		insert();
	}
	printf("%d\n",ans);
	return 0;
}

posted on 2019-01-28 17:13  autoint  阅读(90)  评论(0编辑  收藏  举报

导航