01字典树 详解「建议收藏」

01字典树 详解「建议收藏」欢迎关注我的个人博客:www.zuzhiang.cn以前只知道字典树可以降低空间复杂度,今天无意中接触了01字典树,原来可以用它来降低时间复杂度,下面我就来给大家介绍一下01字典树的原理和应用。01字典树主要用于解决求异或最值的问题。我先放上简单的模板,然后再讲解它的原理。inttol;//节点个数LLval[32*MAXN];//点的值i…


Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

欢迎关注我的个人博客:www.zuzhiang.cn

 

以前只知道字典树可以降低空间复杂度,今天无意中接触了 01字典树,原来可以用它来降低时间复杂度,下面我就来给大家介绍一下 01字典树的原理和应用。

 

 

01字典树主要用于解决求异或最值的问题。我先放上简单的模板,然后再讲解它的原理。

 

int tol; //节点个数 
LL val[32*MAXN]; //点的值 
int ch[32*MAXN][2]; //边的值 

void init()
{ //初始化 
    tol=1;
    ch[0][0]=ch[0][1]=0;
}

void insert(LL x)
{ //往 01字典树中插入 x 
    int u=0;
    for(int i=32;i>=0;i--)
    {
        int v=(x>>i)&1;
        if(!ch[u][v])
        { //如果节点未被访问过 
            ch[tol][0]=ch[tol][1]=0; //将当前节点的边值初始化 
            val[tol]=0; //节点值为0,表示到此不是一个数 
            ch[u][v]=tol++; //边指向的节点编号 
        }
        u=ch[u][v]; //下一节点 
    }
    val[u]=x; //节点值为 x,即到此是一个数 
}

LL query(LL x)
{ //查询所有数中和 x异或结果最大的数 
    int u=0;
    for(int i=32;i>=0;i--)
    {
        int v=(x>>i)&1;
        //利用贪心策略,优先寻找和当前位不同的数 
        if(ch[u][v^1]) u=ch[u][v^1];
        else u=ch[u][v];
    }
    return val[u]; //返回结果 
}

01字典树和普通的字典树原理类似,只不过把插入字符改成了插入二进制串的每一位(0或1)。

 

通过上面的代码,我们可以发现有下面几个事实:

 

1. 01字典树是一棵最多 32层的二叉树,其每个节点的两条边分别表示二进制的某一位的值为 0 还是为 1. 将某个路径上边的值连起来就得到一个二进制串。

2.节点个数为 1 的层(最高层)节点的边对应着二进制串的最高位。

3.以上代码中,ch[i] 表示一个节点,ch[i][0] 和 ch[i][1] 表示节点的两条边指向的节点,val[i] 表示节点的值。

4.每个节点主要有 4个属性:节点值、节点编号、两条边指向的下一节点的编号。

5.节点值 val为 0时表示到当前节点为止不能形成一个数,否则 val[i]=数值。

6.可通过贪心的策略来寻找与 x异或结果最大的数,即优先找和 x二进制的未处理的最高位值不同的边对应的点,这样保证结果最大。

 

 

例题:

一、HDU 4825

传送门:HDU 4825

题目大意:在一组数中找跟某个数异或结果最大的数。

题解:直接套用模板,将数组中的数插入到 01字典树,对每一个数查询即可。

 

二、HDU 5536

传送门:HDU 5536

题目大意:在一个数组中找出 (s[i]+s[j])^s[k] 最大的值,其中 i、j、k 各不相同。

题解:HDU 5536 题解

 

 

三、BZOJ 4260

传送门:BZOJ 4260

题目大意:给你 n 个数,让你求两个不相交的区间元素异或后的和的最大值。

题解:BZOJ 4260 题解

 

 

四、POJ 3764

传送门:POJ 3764

题目大意:在树上找一段路径(连续)使得边权相异或的结果最大。

题解:POJ 3764 题解

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196363.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • videocapture_directshow是什么

    videocapture_directshow是什么DirectShow框架简介DirectShow框架是多媒体播放框架上一个非常经典的框架,现在已经十多年了,在Windows平台上依然无法替代,非常值得去学习研究。个人觉得从设计模式的角度上看,directshow框架的灵活性、复用性、可维护性、可拓展性这些方面做得非常不错,也是它经久不衰历久弥新的一个原因,现在的很多第三方的decoder和filter都基于directshow框架开发,可以很灵活

    2022年10月10日
  • 基于CCXT接口建立的多模块数字货币量化交易模型(MMQT)在python中的实现[通俗易懂]

    基于CCXT接口建立的多模块数字货币量化交易模型(MMQT)在python中的实现[通俗易懂]目录一、前言问题的引出MMQT模型的优势二、MMQT简介1.接口模块2.风控模块3.策略模块4.反馈模块三、MMQT的代码实现1.定义中间模块(类)1.初始化2.获取账户信息、交易对信息、订单信息3.数据更新4.创建订单5.获取订单状态6.撤销订单7.获取k线信息2.定义风控模块(类)3.定义策略模块(类)1.策略模块初始化2.技术分析及交易下单3.反馈模块4.相关类实例化1.ccxt实例化2.中间类、风控类、策略类实例化3.调控程序四、回测的代码实现1.获取数据2.数据清洗3.模拟账户初始化4.回测程序五

    2022年6月26日
  • 查看mysql端口_如何查看db2数据库的端口

    查看mysql端口_如何查看db2数据库的端口mysql端口号(怎么查看mysql的端口号)2020-05-0721:54:58共10个回答如何查看mysql的端口号1使用命令showglobalvariableslike’port’;查看端口号2修改端口,编辑/etc/my.cnf文件,早期版本有可能是my.conf文件名,增加端口参数,并且设定端口,注意该端口未被使用,保存退出.总结:注意修改的端口不要被占用,而且要有规划,不要轻意的总…

    2022年10月3日
  • 23种设计模式(2):工厂方法模式

    23种设计模式(2):工厂方法模式

    2021年11月13日
  • 三字经 全文解读(三字经全文朗读儿童版解读)

    前言:《三字经》自南宋王应麟(字伯厚)先生所创作以来,已有七百多年历史,内容大都采用韵文,每三字一句,四句一组,像一首诗一样,背诵起来,如唱儿歌,三字经是学习中华传统文化不可多得的的儿童启蒙读物,共一千多字,可谓家喻户晓,脍炙人口。内容包括了中国传统的教育、历史、天文、地理、伦理和道德以及一些民间传说,广泛生动而又言简意赅。用来教育子女琅琅上口十分有趣,又能启迪心智,时人觉得本书内容很好,纷纷翻印

    2022年4月10日
  • 2015年逻辑真题难度(2015年逻辑真题)

    说说你对数据库读写分离的理解读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。为什么要分库、分表、读写分?单表的数据量限制,当单表数据量到一定条数之后数据库性能会显著下降。数据多了之后,对数据库的读、写就会很多。分库减少单台数据库的压力。接触过几个分库分表的系统,都是通过主键进行散列分裤分表的。这类数据比较特殊,主键就是唯一的获取该条信息的主要途径。比如

    2022年4月18日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号