【维护异或和】 最大异或对
传送门
题意
给定\(N\)个整数\(A_{1}、A_{2}、\dots A_{n}\),从中选出两个进行异或运算求最大值
数据范围
\(\begin{array}{l}1 \leq N \leq 10^{5} \\ 0 \leq A_{i}<2^{31}\end{array}\)
题解
将数字的二进制\(01\)串作为字符串建立字典树,建立长度为\(30\)的\(01\)字符串,每次查询时,贪心的从高位开始,
每次都将与当前的二进制位不同的计算代表的二进制数字,累加即此数字能够得到的最大值
字典树的长度为\(10^{5} \times 30\) ,在极端情况下每个数字的二进制都不同,每一个数字的二进制有\(30\)位
Code
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
const int N=1e5+10;
int trie[N*30][2],tot=1;
void insert(int x)
{
int p=1;
per(i,0,31)
{
int u=x>>i&1;
if(!trie[p][u]) trie[p][u]=++tot;
p=trie[p][u];
}
}
int query(int x)
{
int p=1;
int res=0;
per(i,0,31)
{
int u=x>>i&1;
if(trie[p][!u])
{
res+=1<<i;
p=trie[p][!u];
}
else p=trie[p][u];
}
return res;
}
void solve()
{
int n;
cin>>n;
int ans=-1e6;
rep(i,0,n)
{
int x;
cin>>x;
insert(x);
ans=max(ans,query(x));
}
cout<<ans<<endl;
}
int main()
{
solve();
}