后缀数组 SA

后缀数组 SA

后缀树组(SA,suffix array),用于处理字符串子串形成的结构。

处理子串的结构主要方式有:后缀数组 SA,后缀自动机 SAM,后缀树 ST

后缀树后缀自动机暂时决定咕咕咕,以后学习可以参考ix35 的字符串复习

含义与实现

后缀

我们定义长度为 \(n\) 的字符串 \(s\) 编号为 \(l\) 的后缀为 \(s\)\([l,s]\) 上的字串,记 \(l\)(即起始位置)为该后缀的编号

后缀树组

如果将 \(s\) 所有 \(n\) 个后缀提取出来,按照字典序升序排序,后缀数组 \(\text{SA}_i\) 定义为排名为 \(i\) 的后缀的编号

那么怎么求出一个字符串的后缀数组呢?

求解

显然暴力找出 \(n\) 个后缀再快速排序的 \(\mathcal{O(n^2\log n)}\) 的(加上比较的复杂度),不够优美。

一般采用 Manber 和 Myers 发明的类似于倍增的方法求解。

(下面图片来自jinkun113 - 后缀数组,如有侵权请告知删除)

如上图,类似每次将两端字符串拼起来形成新的字符串,类似高低进制拼接后再一次排序得到。

通过这样的操作,以 \(i\) 为开头的字串会不断增长到两倍(大于 \(n\) 的用空字符补齐),即不断溢出,最终就得到了 \(n\) 个后缀。

类似这样的倍增求解的方法还可以用于其他的问题,如CF1654F Minimal String Xoration

实现

在上面的过程中,记在 \(i\) 位置上合并的两个数高位的是 \(x_i\),低位的是 \(y_i\),他们记录的是这一部分字串的排名,最终再一次排序后的排名记在 \(x\) 数组内。

这样非常容易写出一个 \(\mathcal{O(n\log^2 n)}\) 的解法,具体就是每次将两端字串合并后,给 \(i\) 赋值为 \(x_i,y_i\) 高低位相接。之后再一次排序并离散化就可以得到新的排名。

//暴力O(n\log^2 n)
int MAX;
int sa[Maxn],First[Maxn],Secon
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值