AcWing 143. 最大异或对
. 最大异或对
一、题目描述
在给定的 个整数 中选出两个进行 (异或)运算,得到的结果最大是多少?
输入格式
第一行输入一个整数 。
第二行输入 个整数 。
输出格式
输出一个整数表示答案。
数据范围
输入样例:
3
1 2 3
输出样例:
3
二、分析思路
先来思考暴力怎么做:
// 最大异或对,用暴力是超时的
// 通过了 6/10个数据
#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N];
int res;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
res=max(res,a[i]^a[j]);
cout<<res<<endl;
return 0;
}
结果不出意外,,只能想办法进行优化
树思路
1、将整数解析为二进制数,即有符号整数,位,就是,按树进行存储, 整数的树存储。
2、每个数字的每一个二进制位,需要从高位到低位,即for(int i = 30; i >= 0; i--)
,想像一下你在构建一个树,那么根就是最高位,然后一路走到位,就是最低位。
3、每个数字想要找到与自己形成最大异或值的另一个数字,我们现在已经把它们保存到树里了,那怎么找呢?什么样的两个数字才是最大异或值的对呢?就是每一位完全相反的就肯定是最大的异或对!那如果某一位相反的结点并不存在呢?这就是退而求其次的思路了,我们尽量从左到右找出与当前数字本位相反的路径,如果存在,就继续探索,如果不存在,那就使用一样的本位值。这样下来,到位,就可以找到和自己匹配最大的异或值。
总结一下
-
里可以用来保存数字,数字需要通过二进制(由高位到低位)进行保存。
-
增加一个数字进来,其实就是增加了一个层级为级的 模拟字符串
-
放入一个数字,那么它肯定会在任意一级(共级)存在一边,另一边可能存在,也可能不存在。
三、实现代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int M = N * 31;
int n, res;
int a[N];
int tr[M][2];
int idx;
// 构建数字二进制位的Trie树
void insert(int x) {
int p = 0;
for (int i = 30; i >= 0; i--) {
int u = (x >> i) & 1; // 取出当前位的值
if (!tr[p][u]) tr[p][u] = ++idx; // 构建Trie树
p = tr[p][u];
}
}
// 所谓与x异或最大,就是利求在高位上尽量不一样,如果找不到不一样的,就只能找一样的,下一个继续优先找不一样的
// 在Trie树中查找到与x异或最大的数
int query(int x) {
int p = 0, ans = 0;
for (int i = 30; i >= 0; i--) {
int u = (x >> i) & 1; // 取出x的当前二进制位
if (tr[p][!u]) { // 如果存在可以异或的路可以走的话,尽量先走
p = tr[p][!u];
ans = ans * 2 + !u; // 还原二进制数字为十进制
} else {
p = tr[p][u]; // 否则只能走与自己本位一样的路线
ans = ans * 2 + u; // 还原二进制数字为十进制
}
}
return ans;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i], insert(a[i]);
for (int i = 1; i <= n; i++) {
int t = query(a[i]);
res = max(res, a[i] ^ t);
}
printf("%d", res);
return 0;
}
五、对于一维数据范围的思考
无论是模板题还是最大异或对着一题
都有这么一行代码
if (!tr[p][u]) tr[p][u] = ++ idx; p = tr[p][u];
所以我们可以知道,数组的一维下标最大值的选取实际上是跟能够自增多少次来决定的
. 字符串统计 中,输入的字符串总长度不超过 ,所以一维值选取
而在 . 最大异或对 中,数字需要以进制进行表示,而每个数字最大为的次幂,所以一维下标应为数字的个数*。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2017-09-14 东师理想资源(可扩展为试题、试卷、微课、备课、作业、精品等其它业务)升级方案