zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    NotifyIcon控件
    JS中的tostring()方法
    WebApp之Meta标签总结
    List<T>用法
    JSON.parse()和JSON.stringify()
    背景图片移动插件MyFloatingBg(浮动背景图效果,可让背景随着页面的滚动而滚动)
    illegal mix of collcations表连接时非法的校对
    truncate 命令删除恢复
    php里 换行问题
    mysql命令行导出导入数据库
  • 原文地址:https://www.cnblogs.com/fx1998/p/13290843.html
Copyright © 2011-2022 走看看