标签:总结 子串 lcp 后缀 height 数组 sa dp
构建过程
基数排序
tips:先比较低位,再比较高位
时间复杂度 o(nk) 其中 k 表示位数
思考:如果我把一个串的位数压缩的尽可能小 ???
倍增优化。考虑每一轮让比较的长度变为原来的两倍。
结构
一些应用
先引入两个新的数组:height[i] 表示 sa[i] 和 sa[i-1] 的最长公共前缀,即 lcp(sa[i-1],sa[i]);h[i] 表示 编号为i 的后缀与排在他前一位的后缀的最长公共前缀,即height[x[i]]。
那么 lcp(sa[i],sa[j]) 可以转化为 RMQ 问题。
知道 h[i] 很容易反推出 height[i] 的值。
一个结论: h[i]>=h[i-1]-1
这里砍掉首位留下来的 border 是很容易发现规律的。
可以线性计算 h 数组 ,复杂度证明使用势能分析。
- 求本质不同的子串个数
2333
- 求至少出现 k 次的子串最大长度
23333333
- 已知排名 k 求子串 (rnm)
例子:bzoj4310 跳蚤
233333333333333
- 多个字符串的问题
例子:spoj220
先将所有字符串连结起来,中间用 不相同的且没有出现在字符串中的 字符隔开(防止两个分隔符相互匹配,即 lcp(i,j) 一定合法),求后缀数组。
然后二分答案,再 将后缀分组 。我们只需要判断同一组后缀中是否每个给定的串都有两个子串不重叠地出现即可。
- 反直觉的 dp 题
例子:CF822E Liar
考察状态的设计和转移 (我的盲区 qwq …)
设 dp[i][j] 表示考虑 a 串中 1~i 的字符,已经选了 j 个子串,在 b 串中能覆盖到的 最大长度 。
这个状态设计只保留了能覆盖到的最大长度。看上去是反直觉的。
这样能够很方便地对 x[i] 和 x[cnt1+dp[i][j]+2] 求 lcp 从而完成转移
那么问题来了,为什么是 lcp ???
假设有一段没有匹配完。那么这一段没有匹配完的部分一定会在下一个子串中被匹配。那么我把这一段移到 s 的后面同样是满足条件的。
至此做到 o(1) 转移。
relax qwq…
标签:总结,子串,lcp,后缀,height,数组,sa,dp 来源: https://blog.csdn.net/cqbzlydd/article/details/122675794
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。