Trie&可持久化Trie
WARNING:以下代码未经测试,若发现错误,欢迎指出qwq~
Trie树(字典树)
一种简单的数据结构,可存储大量字符串,可在$O(len)$的时间内完成插入,删除,查找等操作。
下面是一个简单的例子,对于abc,abd,abcd,bcd这四个字符串建Trie树,如下图:
其中,红色节点为一个字符串的结尾。对于任意节点,从根节点到该节点路径上字符组成的字符串即为该节点表示的字符串。
基本操作
相关变量
int root,cnt,ch[][],son[];
bool flag[];
void init(){
memset(flag,false,sizeof(flag));
memset(son,,sizeof(son));
memset(ch,,sizeof(ch));
root=cnt=;
return;
}
root即为根节点,cnt用于动态建树,ch[i][j]表示i节点的第j个子节点(表示字符char('a'+i))的编号,son[i]表示i节点的子节点数,flag[i]表示i节点是否为某个字符串的末尾。
插入
void ins(int rt,int dep){
if(dep==len){
flag[rt]=true;
return;
}
if(!ch[rt][s[dep]-'a']){
ch[rt][s[dep]-'a']=++cnt;
son[rt]++;
}
ins(ch[rt][s[dep]-'a'],dep+);
return;
}
删除
bool del(int rt,int dep){
if(dep==len){
if(flag[rt]){
flag[rt]=false;
return true;
}
return false;
}
if(!ch[rt][s[dep]-'a'])
return false;
if(del(ch[rt][s[dep]-'a'],dep+)){
if(!son[ch[rt][s[dep]-'a']]&&!flag[ch[rt][s[dep]-'a']]){
ch[rt][s[dep]-'a']=;
son[rt]--;
}
return true;
}
return false;
}
查找
bool query(int rt,int dep){
if(dep==len)
return flag[rt];
if(!ch[rt][s[dep]-'a'])
return false;
return query(ch[rt][s[dep]-'a'],dep+);
}
以上三个是Trie树的基本操作,下面来讲一下Trie树的其它运用。
拓展运用
求第k小字符串
存储以每个节点为根的子树中的末尾节点个数(size[i])即可。
void kth(int rt,int dep,int k){
if(k>size[rt]){
puts("have no kth string");
return;
}
for(int i=;i<;i++)
if(k>size[ch[rt][i]])
k-=size[ch[rt][i]];
else if(ch[rt][i]){
putchar('a'+i);
kth(ch[rt][i],dep+,k);
}
return;
}
最长公共前缀
用LCA求两个字符串对应的末尾节点的最近公共祖先即可,时间复杂度O(log2n)。
代码不贴了,懒~~~
最大异或值
将每个数转化为二进制,添加前缀0至相同位数,然后从最高位开始插入。查询时从最高位开始查询是否有与相应位置异或值为1的节点即可。
太水了,也不贴代码了~~~
可持久化Trie树
在做题过程中,我们常常会遇到求区间第k大字符串,区间与某数异或最大值之内的问题,我们便可以采用可持久化Trie树来解决这类问题。
依旧以abc,abd,abcd,bcd这四个字符串为例建可持久化Trie,如下图:

红色节点意义同上。
基本操作
相关变量
int cnt=,root[],size[],ch[][];
bool flag[];
void init(){
memset(flag,false,sizeof(flag));
memset(root,,sizeof(root));
memset(size,,sizeof(size));
memset(ch,,sizeof(ch));
cnt=;
return;
}
意义同上。
插入
void ins(int &now,int last,int dep){
if(!now)
now=++cnt;
if(dep==len){
flag[now]=true;
size[now]=size[last]+;
return;
}
int sign=s[dep]-'a';
for(int i=;i<;i++)
if(i!=sign){
ch[now][i]=ch[last][i];
size[now]+=size[ch[last][i]];
}
ins(ch[now][sign],ch[last][sign],dep+);
size[now]+=size[ch[now][sign]];
return;
}
区间第k小查询
void kth(int rl,int rr,int dep,int k){
if(k>size[rr]-size[rl]){
puts("have no kth string");
return;
}
for(int i=;i<;i++)
if(k>size[ch[rr][i]]-size[ch[rl][i]])
k-=size[ch[rr][i]]-size[ch[rl][i]];
else if(size[ch[rr][i]]-size[ch[rl][i]]>){
putchar('a'+i);
kth(ch[rl][i],ch[rr][i],dep+,k);
return;
}
return;
}
区间最大异或值
好吧,还是懒得打~~~
Trie&可持久化Trie的更多相关文章
- BZOJ.4212.神牛的养成计划(Trie 可持久化Trie)
BZOJ 为啥hzw的题也是权限题啊 考虑能够匹配\(s1\)这一前缀的串有哪些性质.对所有串排序,能发现可以匹配\(s1\)的是一段区间,可以建一棵\(Trie\)求出来,设为\([l,r]\). ...
- Luogu5283 十二省联考2019异或粽子(trie/可持久化trie+堆)
做前缀异或和,用堆维护一个五元组(x,l,r,p,v),x为区间右端点的值,l~r为区间左端点的范围,p为x在l~r中最大异或和的位置,v为该最大异或和,每次从堆中取出v最大的元素,以p为界将其切成两 ...
- 【BZOJ4137】火星商店问题(线段树分治,可持久化Trie)
[BZOJ4137]火星商店问题(线段树分治,可持久化Trie) 题面 洛谷 BZOJ权限题 题解 显然可以树套树,外层线段树,内层可持久化Trie来做. 所以我们需要更加优美的做法.--线段树分治. ...
- 可持久化Trie模板
如果你了解过 01 Trie 和 可持久化线段树(例如 : 主席树 ).那么就比较好去可持久化 Trie 可持久化 Trie 当 01 Trie 用的时候能很方便解决一些原本 01 Trie 不能解决 ...
- HDU 4757 Tree(可持久化Trie+Tarjan离线LCA)
Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Total Su ...
- 【BZOJ4260】 Codechef REBXOR 可持久化Trie
看到异或就去想前缀和(⊙o⊙) 这个就是正反做一遍最大异或和更新答案 最大异或就是很经典的可持久化Trie,从高到低贪心 WA: val&(1<<(base-1))得到的并不直接是 ...
- 可持久化Trie & 可持久化平衡树 专题练习
[xsy1629]可持久化序列 - 可持久化平衡树 http://www.cnblogs.com/Sdchr/p/6258827.html [bzoj4260]REBXOR - Trie 事实上只是一 ...
- HDU 4757 Tree(可持久化trie)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4757 题意:给出一棵树,节点有权值.每次询问x到y的路径上与z抑或的最大值. 思路:可持久化trie. ...
- 可持久化trie 学习总结
QAQ 以前一直觉得可持久化trie很难,今天强行写了一发觉得还是蛮简单的嘛 自己的模板是自己手写的,写了几道题目并没有出过错误 THUSC的第二题的解法五貌似就是可持久化trie,时间复杂度O(60 ...
随机推荐
- RenderScript on LLVM笔记
Android 为何引入 Render Script: 3D 可移植 ( 直接用 opengl 也能够移植呀?) 性能 易用性 ( 让 opengl 难入门的人,用 Render Script ?) ...
- (WPF)XAML 过程式代码
当代码编译.x:Code 元素的内容将被放到.g.cs文件. <Window x:Class="WpfApplication7.MainWindow" xmlns=" ...
- Sqoop-1.4.6工具import和export使用详解(官网)
不多说,直接上干货! 1.Sqoop Import (进入官网) 因为,sqoop的使用方式是: sqoop COMMAND ARGS. 以下是 sqoop COMMAND ARGS 以下是 ...
- 实测Untangle - Linux下的安全网关
UntangleGateway是一个Linux下开源的的网关模块,支持垃圾过滤.URL阻截.反病毒蠕虫等多种功能,其实他的功能还远不止这些,经过一段时间研究本人特制作本视频供大家参考. 本文出自 &q ...
- OPENCV(3) —— 对XML和YAML文件实现I/O 操作
XML\YAML文件在OpenCV中的数据结构为FileStorage string filename = "I.xml"; FileStorage fs(filename, Fi ...
- python 批量下载文件
file.txt 的内容为: http://183.xxx.xxx.54:188/my/qqq.ico::qq.exe::0::http://183.xxx.xxx.54:186/my/ddnf.ic ...
- 遇到的兼容性bug
1.(IE6):ie6环境下,通过设置z-index:999:无效果: 原因:IE6下,决定层级高低的不是当前的父标签,而是整个DOM tree(节点树)的第一个relative属性的父标签. 解决办 ...
- Android manifest文件中的标签详细介绍
官方文档 概要 每一个Android应用都应该包含一个manifest文件,即AndroidManifest.xml.它包含了程序运行的一些必备信息,比如:--为Java应用程序指定一个独一无二的名字 ...
- 【hiho39】二分·归并排序之逆序对
近期申请了微软的暑假实习,4号就要在线笔试了,在线測试系统用的是http://hihocoder.com/,今天试手做了一道题. [题目] 原题链接:http://hihocoder.com/cont ...
- Visual Studio Set Project Environment Variables
Visual Studio Set Project Environment Variables eryar@163.com In Visual Studio you can specify chang ...