• 9.最大异或对 Trie树


     可以选俩一样的数,但自己异或自己结果是0,不是最优解

    预备知识,啥是异或

     

     暴力做法就是两层for循环枚举所有可能

     暴力的思路就是

    1:首先选定一个Ai(1 <= i <= n)

    2:在A1 ~ An中选择一个数Aj,使得Ai ^ Aj的值最大

    突破点在第2步

    首先Ai一定小于等于31位,也就是0 <= Ai <= 2 ^ 31 - 1

     本题思路:

    首先对所有的Ai,根据每一位的0和1,建立一个Trie树

     然后对于每一个固定的Ai的话

    在Trie树中寻找,从根节点往下走

    每次尽量往和Ai这一位上的数字不同的数字这一个分支上走,这样才能使得两个数异或出来的值最大

    模拟样例

     时间复杂度10 ^ 5 * 31

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int N = 100010, M = 4e6 + 10;
     4 //M是Trie的总节点个数 = 10 ^ 5 * 31
     5 int a[N], son[M][2], idx;
     6 void insert(int x) {
     7     int p = 0;
     8     for (int i = 30; i >= 0; i--) {
     9         int &s = son[p][x >> i & 1];
    10         if (!s) {
    11             s = ++ idx; //创建新结点
    12         }
    13         p = s;
    14     }
    15 }
    16 int query(int x) { //找到和x异或值最大的结果
    17     int p = 0;
    18     int res = 0;
    19     for (int i = 30; i >= 0; i--) {
    20         int s = x >> i & 1;
    21         if (son[p][!s]) {
    22             res += 1 << i;
    23             p = son[p][!s];
    24         } else {
    25             p = son[p][s];
    26         }
    27     }
    28     return res;
    29 }
    30 int main() {
    31     int n;
    32     cin >> n;
    33     for (int i = 0; i < n; i++) {
    34         cin >> a[i];
    35         insert(a[i]);
    36     }
    37     int res = 0;
    38     for (int i = 0; i < n; i++) {
    39         res = max(res, query(a[i]));
    40     }
    41     cout << res << endl;
    42     return 0;
    43 }
  • 相关阅读:
    生成lua的静态库.动态库.lua.exe和luac.exe
    Eclipse 常用快捷键 (动画讲解)
    Lua table之弱引用
    编程语言简史(转)
    sublime text 下的Markdown写作
    使用python拼接多张图片.二三事
    Lua标准库- 模块(Modules)
    lua的私有性(privacy)
    Lua字符串库(整理)
    字符编码的故事(转)
  • 原文地址:https://www.cnblogs.com/fx1998/p/13290843.html
Copyright © 2020-2023  润新知