视频加载失败

字典树

683 字
3 分钟
字典树

数据结构

特点:字典树支持高效的前缀查找。其次,通过共享前缀来节省空间,多个以相同前缀开头的字符串只需存储一份前缀。再次,字典树的节点不直接存储完整的字符串,而是通过从根节点到该节点的路径构成字符串 最后,字典树支持插入、查找、删除和前缀匹配等多种操作 插入和查找操作的时间复杂度均为 O(m),其中 m 是字符串的长度

结构定义:字典树通常由两个主要结构组成。首先是TrieNode(节点),每个节点包含一个子节点的映射(通常使用哈希表或数组)和一个布尔值 end,指示该节点是否为某个字符串的结尾。其次是Trie(字典树),它包含一个指向根节点的指针,所有字符串的插入和查找操作都从根节点开始

struct trie {
int nex[100000][26], cnt;
bool exist[100000]; // 该结点结尾的字符串是否存在
void insert(char *s, int l) { // 插入字符串
int p = 0;
for (int i = 0; i < l; i++) {
int c = s[i] - 'a';
if (!nex[p][c]) nex[p][c] = ++cnt; // 如果没有,就添加结点
p = nex[p][c];
}
exist[p] = true;
}
bool find(char *s, int l) { // 查找字符串
int p = 0;
for (int i = 0; i < l; i++) {
int c = s[i] - 'a';
if (!nex[p][c]) return 0;
p = nex[p][c];
}
return exist[p];
}
};

维护异或极值#

XOR 异或 将数的二进制表示看做一个字符串,就可以建出字符集为 {0,1}\{0,1\} 的 trie 树。

Problem - 706D - Codeforces

我们考虑在一个01字典树(每个节点是0或1)里插入所有数的二进制表示。比如要插入一个32位整数,就从高位到低位一位一位插。

插入过程:

  • 从最高位(比如31位)往最低位0位走。
  • 每一位如果是0,就走/建0儿子,否则走/建1儿子。

查询最大异或值的过程: 假设现在要查一个数x,想找集合中一个数,使得异或值最大。异或要大,意味着尽量在每一位上异或出1。怎么做?

  • 从高位到低位一位一位走。
  • 每一位,优先找跟x当前位不同的方向(因为1异或0 = 1,能让结果高位出现1)。
  • 如果能走,就走异位;不能走,就只能走同位。
  • 边走边计算异或值。

查询最小异或值的过程(比如如果需要):

  • 每一位,优先走跟x当前位相同的方向(因为0异或0=0,1异或1=0,结果小)。
  • 走不了再走异位。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

字典树
https://blog.81vm3.xyz/posts/trie/
作者
Blume
发布于
2024-09-22
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Blume
I build interesting things.
公告
欢迎来到我的博客!
分类
标签
最新动态
站点统计
文章
38
分类
5
标签
98
总字数
23,078
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录