[AcWing 143] 最大异或对


点击查看代码
#include<iostream>

using namespace std;
const int N = 1e5 + 10;
const int M = 5e6 + 10;
int son[M][2], idx;
int a[N];
void insert(int x)
{
    int p = 0;
    for (int i = 30; i >= 0; i --) {
        int& s = son[p][x >> i & 1];
        if (!s)     s = ++ idx;
        p = s;
    }
}
int query(int x)
{
    int p = 0, res = 0;
    for (int i = 30; i >= 0; i --) {
        int s = x >> i & 1;
        if (son[p][!s]) {
            res += 1 << i;
            p = son[p][!s];
        }
        else    p = son[p][s];
    }
    return res;
}
int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i ++) {
        cin >> a[i];
        insert(a[i]);
    }
    int res = 0;
    for (int i = 0; i < n; i ++)    res = max(res, query(a[i]));
    cout << res;
    return 0;
}

  1. 对每一个 a[ i ],使用字典树,找到和 a[ i ] 异或最大的数(从高位开始,如果 a[ i ] 的这一位等于 1,若字典树中有这一位为 0 的分支,则指针 p 就移动到 0 的分支上,如果没有,p 就移动到 1 的分支上);
  2. M 的意义是字典树中节点的个数,一共有 N 个数,每个数对应 31 个节点,总共最多有 1e5 × 31 = 3e6 + 1e5 个节点,取 M 为 5e6 + 10 是足够的;
  3. insert 操作,s 是当前节点的孩子节点的 idx 值,因为需要对其进行修改,故用 &s 来进行更改;
  4. 查找时,若存在异或的分支就把 res += 1 << i,否则,res 不修改;
posted @   wKingYu  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
欢迎阅读『[AcWing 143] 最大异或对』
点击右上角即可分享
微信分享提示