zoukankan      html  css  js  c++  java
  • 0/1字典树

    参考博客:https://blog.csdn.net/weixin_43847416/article/details/95048031

         https://blog.csdn.net/qq_41292370/article/details/90680145

    01字典树主要用于解决求异或最值的问题。01字典树的插入和查找操作跟字典树基本上差不多,只是字典树插入的是一个字符串,而01字典树插入的是一个二进制的数字串

    现在来说说为什么01字典树可以解决异或最值问题:假如现在给出一个数,现在我们要找一个数与该数异或值最大,我们应该怎么找,这里我们要用的(0^1=1,0^0=0,1^1=0)基本异或操作,现在我们只需要把这个数化成二进制数,然后从高位依次向下找(为什么从高位开始找,后面再解释),如果这个数该位是0,我们就要找该位是1的数,要是该位是1的话,我们就要找该位是0的数。例如:我们要找二进制为1001的数的异或最大值,另一个数肯定是0110,这样异或下来为1111,结果最大。

    • 01字典树就是一棵最多 32层(如果插入的数在int型之内)的二叉树,其每个节点的两条边分别表示二进制的某一位的值为 0 还是为 1. 将某个路径上边的值连起来就得到一个二进制串。
    • 节点个数为 1 的层(最高层)节点的边对应着二进制串的最高位。
    • 可通过贪心的策略来寻找与 x异或结果最大的数,即优先找和 x二进制的未处理的最高位值不同的边对应的点,这样保证结果最大。

    模板:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=2e6+5;
     5 
     6 int n,m;
     7 int tris[maxn][2];
     8 ll val[maxn];                                               //节点值
     9 ll num[maxn];                                               //记录每个节点被访问的次数
    10 int tot;
    11 
    12 void _insert(ll x){                                         //插入d
    13     int root=0;
    14     for(int i=32;i>=0;i--){
    15         int id=(x>>i)&1;                                    //获得二进制位的值
    16         if( !trie[root][id] ) trie[root][id]=++tot;
    17         root=trie[root][id];
    18         num[root]++;                                        //记录该节点被访问几次
    19     }
    20     val[root]=d;                                            //记录值
    21 }
    22 
    23 ll find_(ll x){                                             //查询所有数中和x异或结果最大的数
    24     int root=0;
    25     for(int i>=32;i>=0;i--){
    26         int id=(x>>i)&1;
    27         if( trie[root][id^1] ) root=trie[root][id^1];       //利用贪心策略,优先寻找和当前位不同的数
    28         else root=trie[root][id];
    29     }
    30     return val[root];
    31 }
  • 相关阅读:
    Leetcode Reverse Words in a String
    topcoder SRM 619 DIV2 GoodCompanyDivTwo
    topcoder SRM 618 DIV2 MovingRooksDiv2
    topcoder SRM 618 DIV2 WritingWords
    topcoder SRM 618 DIV2 LongWordsDiv2
    Zepto Code Rush 2014 A. Feed with Candy
    Zepto Code Rush 2014 B
    Codeforces Round #245 (Div. 2) B
    Codeforces Round #245 (Div. 2) A
    Codeforces Round #247 (Div. 2) B
  • 原文地址:https://www.cnblogs.com/wsy107316/p/12305280.html
Copyright © 2011-2022 走看看