【学习笔记】带你从0开始学习 01Trie
1|001Trie
1|1Section 1:普通 Trie
Section 1.1 什么是 Trie
Trie 树,即字典树,是一种树形结构。典型应用是用于统计和排序大量的字符串前缀来减少查询时间,最大限度地减少无谓的字符串比较。
Section 1.2 如何实现
具体地说,对于每个结点,我们要保存几个信息:
ch[26]
,保存此字符的下一个字符( )的存储地址(没有为 )。cnt
,保存此节点被经过了多少次。
对于整个 Trie 树,我们还要额外保存
Tcnt
,为节点数。Endp[]
,表示的是这个字符串是否以这个下标结尾(如果只是看是否是前缀,则不需要此数组)。
几个操作
insert
:往 Trie 树里插入一个字符串。
具体实现:把字符串里的字符扫描一遍,设当前字符为 ch[s-'a']
不等于 ch[s-'a']
的存储下标。否则把 ch[s-'a']
设为树的节点数加一,然后跳转。跳转时把当前节点的
跳到最后把当前节点
find
:查询 Trie 里是否有这个字符串。
具体实现:根据每个字符一个一个跳。
如果跳的时候
如果跳到最后,有,但是
否则有这个字符串,返回 true
。
Section 1.3 代码实现
(只给出基础的插入和查询出现次数)
点击查看代码
Section 1.4 模板
(使用以上代码无法通过此题,请写
1|2Section 2:01Trie
Section 2.1 什么是 01Trie?
和普通 Trie 相似,但是每个节点只有两个值:
从根节点至下的一条路径保存着一个正整数从高到低的二进制位。
如下图:
中序遍历结果为(忽略根节点):
我们会发现几点有趣的性质:
- 01Trie 是一棵二叉树,每个节点的左儿子为
,右儿子为 。 - 从根节点往下,所有左儿子开始的路径值都小于右儿子开始的路径值。
运用这两点性质,我们就可以用 01Trie 造一棵平衡树。
Section 2.2 平衡树
对于每个节点,我们维护两个信息:
siz
,维护以当前节点为根节点的子树大小。cnt
,维护数字到当前节点为二进制的最后一位的数字个数。
此外,和普通 Trie 一样,我们还要维护树的大小
几个操作
-
insert
:平衡树的插入操作。首先,给每个经过的结点的 加一,表示子树节点的个数多了一个。如果当前数字的当前二进制位为 ,就把他放在左儿子,否则放在右儿子。插入到最后一位时给当前节点的 加 。 -
delete
:平衡树的删除操作,与insert
几乎一样,只是把最后一位 就行了。 -
get_rank
:查询当前数的排名。从根节点开始往下,如果当前数的当前二进制位为 ,就把排名加上它的左子树的值(性质二)。 -
get_kth
:查询排名为 的数。从根节点往下,设它的左子树 为 ,则如果 ,则说明排名为 的节点在它的左子树上。否则向右子树查找,并把答案的当前二进制位设为 。 -
pre
:求当前数的前驱。返回get_kth(get_rank(x))
即可。 -
nxt
:求当前数的后继。返回get_kth(get_rank(x+1)+1)
即可。
Section 2.3 代码实现
点击查看代码
Section 2.4 模板
1|3Section 3:01Trie 例题
Description
给定一棵树和树上的边权,求两点之间路径异或值的最大值。
Solution
先给定一个前置知识:
所以树上两点路径的异或值等于根节点分别向两点的路径异或值的异或(
所以我们可以一遍 dfs 处理出根节点到所有节点的边权异或值,随后把它们扔进 01Trie 中。为了让异或值最大,我们可以枚举节点,在 Trie 上贪心:从高到低位,尽量选和当前数二进制位不一样的,随后再与原节点异或值异或一下,取
Code
点击查看代码
__EOF__

本文链接:https://www.cnblogs.com/TheSky233/p/16502346.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?