[AcWing] 143. 最大异或对(C++实现)---trie例题

1. 题目

在这里插入图片描述

2. 读题(需要重点注意的东西)

思路:

异或:
如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。(相同为0,不同为1
如 1(十进制) = 0001(2进制), 2 = 0010, 3 = 0011
1 ⊕ 2 = 0011 = 3, 1 ⊕ 3 = 0010 , 2 ⊕ 3 = 0001 —> 异或得到最大值为 3

解题过程:
① 将所有的数建trie在这里插入图片描述

② 然后让每个数走一遍trie(当前位上为0则在trie上走1,当前位上为1则在trie上走0,然后继续看下一位),得到的结果与其进行异或,就是该数的最大异或
③ 对所有数的最大异或取max,即为答案

3. 解法

---------------------------------------------------解法---------------------------------------------------

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010, M = 3100010;

int n;
int a[N], son[M][2], idx;

void insert(int x)
{
    int p = 0;
    for (int i = 30; i >= 0; i -- ) // i >= 0 等价于 ~i ,因为-1 = 111...1,取反-1就是0
    {
        int &s = son[p][x >> i & 1];
        if (!s) s = ++ idx; // 创建一个新节点
        p = s;
    }
}

int search(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()
{
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ )
    {
        scanf("%d", &a[i]);
        insert(a[i]); // 将每个数插入trie树中
    }

    int res = 0;
    for (int i = 0; i < n; i ++ ) res = max(res, search(a[i])); // 求出每个数的最大异或值,再求max
 
    printf("%d\n", res);

    return 0;
}

可能存在的问题(所有问题的位置都在上述代码中标注了出来)

4. 可能有帮助的前置习题

5. 所用到的数据结构与算法思想

  • Trie 前缀树

6. 总结

Trie 前缀树的例题,理解思想并实现代码。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cloudeeeee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值