trie上构建后缀数组
例题:
往事太多,有时候忘了就忘了吧。
如果有非记不可的,就只能用点附加手段啦!
我们定义一棵往事树是一个 n 个点 n-1 条边的有向无环图,点编号为 1到 n,其中 1 号点被称为是根结点,除根结点以外,
每个点都恰有一条出边(即以其作为起点的边)。
每条边上有 1 个字符(这里我们实际上用一个不大于 300的非负整数代表不同的字符),
对于任意一个点 u,u 的所有入边(即以其为终点的边)上的字符互不相同。
接下来我们定义往事,点 u 对应的往事为 u 到根的路径(显然有且只有一条)上的所有边按照从 u 到根经过的顺序排序后边上的字符依次拼接形成的字符串,简记为 r(u)。
一棵往事树的联系度取决于它包含的所有往事之中最相近的一对的相似度。具体的,我们定义 2 个点 u 和点 v 对应的往事的相似度 f(u,v)如下。
\(f(u,v)=Lcp(r(u),r(v))+Lcs(r(u),r(v))\)
其中 Lcp(a,b)表示字符串 a 和 b 的最长公共前缀的长度, Lcs(a,b)表示字符串a 和 b 的最长公共后缀的长度。
定义一棵往事树的联系度为所有满足 1<=u<v<=n 的 f(u,v)的最大值。
现在,给出一棵往事树,请你给出这棵往事树的联系度。
题解:
首先,将所有r(u)排序,这样,lcp就是相邻的r(u)的lcp的RMQ。(原理同后缀数组)
所以,排序后离得越近,lcp就越长。
显然,lcs就是lca的深度。
所以,枚举lca,即对树进行dfs,每次合并所有子树,并能询问所有间隔最近的RMQ的最大值。
用线段树合并,维护每个区间的lcp最大值,排名最大的节点,排名最小的节点,pushup时考虑左子节点的最大值和右子节点的最小值。
这步的时间复杂度是nlogn的。
考虑如何排序:
直接qsort,每次cmp二分+hash比较大小是logn的,总时间复杂度是nlog^2n的。
考虑另一种做法:
若我们已知长度为x的串的大小关系(排名),那么,我们将长度为x的串拼接在一起,就能得到长度为2x的串。
将长度为2x的串的前半部分的排名作为第一关键字,后半部分的排名作为第二关键字,排序后就能得到长度为2x的串的大小关系,进而得出长度为2x的串的排名。
然后,我们就可以继续这个过程,从而将所有r(u)排序。
由于排名是0~n的,所以可以采用基数排序,每轮时间复杂度是线性的,共logn轮,所以总时间复杂度是nlogn。
其实就是后缀数组的方法。
现在考虑求height(好像不能用后缀数组的那个方法):
方法一:二分+hash。
方法二:倍增,每次考虑x往上长度为2^i的串与y往上长度为2^i的串是否相等。
可以发现,这些串,在倍增排序时就考虑过了,若排名相等,这两个串就相等。将每次倍增排序的排名记录下来就行了。
总时间复杂度:\(O(nlogn)\)。
代码没了。
trie上构建后缀数组的更多相关文章
- bzoj3926/luoguP3346 [Zjoi2015]诸神眷顾的幻想乡(trie上构建广义后缀自动机)
bzoj3926/luoguP3346 [Zjoi2015]诸神眷顾的幻想乡(trie上构建广义后缀自动机) bzoj Luogu 题解时间 给你个无根trie树(你管这叫trie树?),问你选取一条 ...
- 后缀树 & 后缀数组
后缀树: 字符串匹配算法一般都分为两个步骤,一预处理,二匹配. KMP和AC自动机都是对模式串进行预处理,后缀树和后缀数组则是对文本串进行预处理. 后缀树的性质: 存储所有 n(n-1)/2 个后缀需 ...
- 笔试算法题(40):后缀数组 & 后缀树(Suffix Array & Suffix Tree)
议题:后缀数组(Suffix Array) 分析: 后缀树和后缀数组都是处理字符串的有效工具,前者较为常见,但后者更容易编程实现,空间耗用更少:后缀数组可用于解决最长公共子串问题,多模式匹配问题,最长 ...
- [bzoj3879]SvT_后缀数组_RMQ_单调栈
SvT bzoj-3879 题目大意:给定一个字符串.每次询问给定$t$个位置,求两两位置开头的后缀的$LCP$之和. 注释:$1\le length\le 5\cdot 10^5$,$\sum t\ ...
- [bzoj3238][Ahoi2013]差异_后缀数组_单调栈
差异 bzoj-3238 Ahoi-2013 题目大意:求任意两个后缀之间的$LCP$的和. 注释:$1\le length \le 5\cdot 10^5$. 想法: 两个后缀之间的$LCP$和显然 ...
- SPOJ 694 Distinct Substrings/SPOJ 705 New Distinct Substrings(后缀数组)
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
- CF 504E Misha and LCP on Tree——后缀数组+树链剖分
题目:http://codeforces.com/contest/504/problem/E 树链剖分,把重链都接起来,且把每条重链的另一种方向的也都接上,在这个 2*n 的序列上跑后缀数组. 对于询 ...
- BZOJ2119: 股市的预测(后缀数组)
Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工 具,它通过一张时间与股票的价位的函数图像清晰地展示了股票的走势情况.经过长 ...
- Boring counting HDU - 3518 (后缀数组)
Boring counting \[ Time Limit: 1000 ms \quad Memory Limit: 32768 kB \] 题意 给出一个字符串,求出其中出现两次及以上的子串个数,要 ...
随机推荐
- SrpingBoot入门到入坟02-HelloWorld的细节和初始自动配置
关于SpringBoot的第一个HelloWorld的一些细节: 1.父项目 首先查看项目中的pom.xml文件 文件中有个父项目,点进去则: 它里面也有一个父项目,再点进去: 可以发现有很多的依赖版 ...
- docker 实践三:操作容器
在学习了 docker 镜像的内容后,我们在来看 docker 的另一个核心点:容器. 注:环境为 CentOS7,docker 19.03 docker 的容器是镜像的一个运行实例.docker 镜 ...
- 使用Duilib开发Windows软件(1)——HelloWorld
我使用的是网易版本: https://github.com/netease-im/NIM_Duilib_Framework 时间是2019-11-28,作者最新的提交如下图: 运行官方示例程序 下载完 ...
- 画一个秘密花园 | Scratch 3.0 艺术项目
项目类型:艺术 难度指数:3.5颗星 适合年龄:9岁以上 角色个数:1 程序个数:1 学习时长:建议60min——90min 项目内容: 点击绿色旗子,音乐声响起.随后在舞台上点击一下,就出现一朵花, ...
- CMake入门-03-还是HelloWorld
工作环境 系统:macOS Mojave 10.14.6 CMake: Version 3.15.0-rc4 Hello,World! 扩展-math 目录里的文件编译成静态库再由 main 函数调用 ...
- linux 串口接收
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types. ...
- HTTP method GET is not supported by this URL
Servlet eroor:HTTP method GET is not supported by this URL 错误提示: type: Status report message: HTTP m ...
- reference website
reference website cplusplus http://www.cplusplus.com/reference/ cppreference https://en.cppreference ...
- 分享一张理解数据库inner join,left join,right join,full join的图
- vue的自定义指令
点击元素之外触发函数 <template> <div v-clickoutside="clickItemOut"></div> </tem ...