字典树(Trie)
字典树(Trie)
Trie 是一种能够快速插入和查询字符串的多叉树结构。
节点的编号各不相同,根节点编号为
还可以标记单词插入的次数。边表示字符。
一般情况下,Trie维护字符串的集合,支持以下两种操作:
1.向集合中插入一个字符串。
2.向集合中查询一个字符串。
建字典树
子数组 ch[p][j]
表示从节点
计数数组 cnt[p]
表示以节点
节点编号 idx
用来给节点编号。
1.Trie中只有一个根节点,编号为0。
2.从根开始插入,枚举字符串的所有字符。
如果有儿子,那么直接走到儿子。
反之,先创建儿子,再走到儿子。
3.维护计数数组。
int ch[N][26],cnt[N],idx;
void insert(string s){
int p=0;
for(auto c:s){
int j=c-'a';
if(!ch[p][j]) ch[p][j]=++idx;
p=ch[p][j];
}
cnt[p]++;
}
int query(string s){
int p=0;
for(auto c:s){
int j=c-'a';
if(!ch[p][j]) return 0;
p=ch[p][j];
}
return cnt[p];
}
0-1 Trie 解决异或和相关问题
将整数转化成2进制后,将其存入Trie中。利用贪心思想即可求出最大异或和。
int ch[N*33][2],idx;
int sz[N*33];
void ins(i64 x){
for(int i=32,p=0;i>=0;i--){
int j=x>>i&1;
if(!ch[p][j]) ch[p][j]=++idx;
p=ch[p][j];
sz[p]++;
}
}
void del(i64 x){
for(int i=32,p=0;i>=0;i--){
int j=x>>i&1;
p=ch[p][j];
--sz[p];
}
}
i64 query(i64 x,int rk){
i64 ret=0;
for(int i=32,p=0;i>=0;i--){
int j=((x>>i)&1);
if(!ch[p][j^1]) p=ch[p][j];
else if(rk<=sz[ch[p][j^1]]){
p=ch[p][j^1];
ret|=1LL<<i;
}else{
rk-=sz[ch[p][j^1]];
p=ch[p][j];
}
}
return ret;
}
这个板子可以解决求出
例题: HDU4825]Xor Sum - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
并且多维护了一个
例题:HDU5536]Chip Factory - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
还有一类经典的问题--最大区间异或。
给你一个数组求出最大区间异或。根据异或的性质,我们可以维护出前缀异或数组。
那么
最大异或和 问题。
对于 最大不相交区间异或和 ,我们可以再多维护一个后缀异或和数组。多处理一次即可。记得清空Trie树。
例题: Codechef REBXOR]Nikitosh and xor - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
经典问题--最长异或路径
求
那么
根据异或的性质,多的那部分刚好相互抵消。
因此有
所以我们只要维护一下每个节点到根节点的异或和,剩下的步骤就和最大异或值处理一样。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】