[AcWing]143. 最大异或对
原创
©著作权归作者所有:来自51CTO博客作者LibreCoder的原创作品,请联系作者获取转载授权,否则将追究法律责任
算法标签 Trie字典树贪心
来源 《算法竞赛进阶指南》
题目简叙
![在这里插入图片描述 [AcWing]143. 最大异或对_ci](https://s2.51cto.com/images/blog/202303/20141737_6417fa81c626669130.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
思路
使用二叉树的结构来表示整个插入和查询过程:
![在这里插入图片描述 [AcWing]143. 最大异或对_ios_02](https://s2.51cto.com/images/blog/202303/20141738_6417fa821c72912813.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
代码
#include<iostream>
using namespace std;
const int N=1e5+10;
int tree[N*31][2];
int idx,p;
void insert(int x){
p=0;
for(int i=30;~i;i--){//这里是30的原因是因为限制从0到30,我们采用高位优先,这样可以从大值直接判断
int u=x>>i&1;//获取当前位置上的二进制数值
if(!tree[p][u])tree[p][u]=++idx;//如果不存在,则创建,并指向下一个位置
p = tree[p][u];//移动下一个位置
}
}
int query(int x){
p=0;
int tmpres=0;//用来表示与X异或操作的最大的值
for(int i=30;~i;i--){
int u=x>>i&1;
if(tree[p][!u]){//如果存在和当前U相反的值,就选取,这样数值会更大
tmpres=tmpres*2+!u;//tmpres为二进制状态,进一位+(!u)
p =tree[p][!u];//移动到下一个
}
else {
tmpres=tmpres*2+u;
p =tree[p][u];
}
}
return (tmpres^=x);//两个值进行异或操作
}
int main(){
int n;
cin>>n;
int tmp;
int res=0;
while(n--){
cin>>tmp;
insert(tmp);
res=max(res,query(tmp));//用res维护一个最大值
}
cout<<res;
return 0;
}
AC记录
![在这里插入图片描述 [AcWing]143. 最大异或对_ios_03](https://s2.51cto.com/images/blog/202303/20141738_6417fa8232c8542257.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)