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 ...
随机推荐
- Looger级别
Logger级别 日志记录器(Logger)是日志处理的核心组件.log4j具有5种正常级别(Level).日志记录器(Logger)的可用级别Level (不包括自定义级别 Level), 以下内容 ...
- Import .bak file to a database in SQL server
https://stackoverflow.com/questions/1535914/import-bak-file-to-a-database-in-sql-server On SQL Serve ...
- ajax --- Ajax跨域请求保证同一个session的问题
我们知道,根据浏览器的保护规则,跨域的时候我们创建的sessionId是不会被浏览器保存下来的,这样,当我们在进行跨域访问的时候,我们的sessionId就不会被保存下来,也就是说,每一次的请求,服务 ...
- tomcat7 bootstrap
tomcat7 bootstrap http://t5crambing.iteye.com/blog/1923636
- [Javascript] Specify this using .call() or .apply()
A function's this argument is usually set implicitly, depending on how the function is called. Ordin ...
- U盘版Windows 10已经在亚马逊Amazon開始接受预订啦
Windows 10定于下周7月29日正式公布. Windows 10家庭版119美元.专业版199美元,这个价格包含 Windows 10 授权.
- Scala学习之爬豆瓣电影
简单使用Scala和Jsoup对豆瓣电影进行爬虫,技术比較简单易学. 写文章不易,欢迎大家採我的文章,以及给出实用的评论,当然大家也能够关注一下我的github:多谢. 1.爬虫前期准备 找好须要抓取 ...
- button-xml 中android:clickable="false" 属性
今天在做项目的时候,遇到了一个问题,就是需要把一个常按监听事件,加到一个linearlayout中,但是,这个linearlayout中有其他的button.textview等控件,这样就导致当我们常 ...
- Excel的版本
https://en.wikipedia.org/wiki/Microsoft_Excel 取自维基百科,需要特别注意的是,从v12开始,有很大的改变.后缀名从xls变为xlsx Versions 5 ...
- 安装Domino分区服务器
主要是修改修改notes.ini文件 •所有分区服务器使用同一个 IP 地址 指定不同端口 ,端口映射服务器使用端口号1352.建议对其他分区服务器使用端口号 1352以后的TCPIP_Tcp ...