后缀数组 - 总结

构建过程

基数排序

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…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值