后缀数组SA学习
概述
后缀数组SA顾名思义是通过对字符串后缀的处理,解决一类问题
定义
后缀:${\rm suffix}(i)$表示字符串 $s$ 从第 $i$ 个位置开始的后缀,即由 $s[i]$ ~ $s[n−1]$ 组成的子串。
后缀数组:${\rm SA}[\ ]$保存了对字符串 $s$ 的所有后缀排序后的结果。 ${\rm SA}[i]$表示第 $i$ 小的后缀在原串中的起始位置。
名次数组:${\rm rank}[\ ]$ ,按起始位置保存了每个后缀在 ${\rm SA}[\ ]$ 中的排名。 ${\rm rank}[i]$ 表示 ${\rm suffix}(i)$ 的排名,即
${\rm rank}[{\rm SA}[i]]=i$(第 $i$ 小的后缀的排名为 $i$ )。
高度数组:${\rm height}[\ ]$,保存了后缀数组 ${\rm SA}[\ ]$ 相邻两个后缀的最长公共前缀$({\rm LCP})$
$$
{\rm height}[i] = \begin{cases} 0 & i = 0 \ {\rm LCP}({\rm suffix}({\rm SA}[i]), {\rm suffix}({\rm SA}[i - 1])) & i > 0 \ \end{cases}
$$
即 $ {\rm height}[i] $ 表示存在的最大的 $ x $,满足对于任何 $ k \in [0, x) $ 有 $ s[{\rm SA}[i] + k] = s[{\rm SA}[i - 1] + k] $。
值得注意的是,$ {\rm height}[0] $ 的值是无效的,因为排名最靠前的后缀没有前一名。
原理
见Menci blog
模板
1 | // 字符串输入从0开始 |