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

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

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

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)
上一篇 2025年9月28日 下午1:43
下一篇 2025年9月28日 下午2:22


相关推荐

  • 四款常见数据库比较同步软件汇总

    下载网站:www.SyncNavigator.CN  客服QQ1793040———————————————————-  关于HKROnlineSyncNavigator注册机价格的问题HKROnlineSyncNavigator 8.4.1企业版数据同步软件自2009年第一个版本开发…

    2022年4月3日
    2.0K
  • unbuntu安装google浏览器和谷歌浏览器驱动

    unbuntu安装google浏览器和谷歌浏览器驱动1、安装google浏览器sudowgethttp://www.linuxidc.com/files/repo/google-chrome.list-P/etc/apt/sources.list.d/wget-q-O-https://dl.google.com/linux/linux_signing_key.pub|sudoapt-keyadd-sudoapt-…

    2022年6月11日
    35
  • MySQL索引失效的几种场景

    MySQL索引失效的几种场景

    2021年11月10日
    60
  • 解决virtualbox虚拟机桥接模式下不能上网

    解决virtualbox虚拟机桥接模式下不能上网virtualbox虚拟机桥接模式下不能上网欢迎使用Markdown编辑器欢迎使用Markdown编辑器https://blog.csdn.net/wild46cat/article/details/53100931跟着这个链接操作在主机上设置好网络然后在虚拟机上设置,也是跟着其他作者教程做的,一时找不到那个网页了vim/etc/resolv.confvim/etc/network/interfaces/…

    2022年6月10日
    67
  • linux修改密码长度限制_linux文件名长度限制修改

    linux修改密码长度限制_linux文件名长度限制修改修改密码长度:设置为不少于8位的。修改最短密码长度需要编辑login.defs文件(vi/etc/login.defs),把下面这行PASS_MIN_LEN5(默认的情况)改为PASS_MIN_LEN8(修改后的情况)login.defs文件是login程序的配置文件 转载于:https://blog.51ct…

    2025年9月19日
    6
  • linux重启_ubuntu网卡重启

    linux重启_ubuntu网卡重启本文用于备忘!如果我们修改了ip,如果没有重启网卡,一般是没有奏效的。Linux下网卡重启的命令为:/etc/init.d/networkrestart或者是/etc/init.d/networkingrestart或者重启网络服务:servicenetworkrestart在ubuntu下,还可以指定控制哪个网卡(其中eth0为网卡名):sudoifdown

    2026年2月13日
    6

发表回复

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

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