后缀数组 & 后缀自动机

本篇博文同时也作为 WC2021 Day2 的附文。

后缀数组

定义

后缀是什么?\(suffix_i = s_{i \cdots |s|}\)

后缀数组包括 \(sa_i, rk_i\)。分别表示将 \(s\) 的所有后缀排序后,排名第 \(i\) 小的后缀的起始位置,和起始位置在 \(i\) 上的后缀的排名。

注:这里的“排名”指的是对这些后缀按照字典序排序后的排名。如果现在还不清楚什么是字典序,请自行搜索。

在阅读接下来的内容之前,请务必清楚理解 \(sa_i\)\(rk_i\) 的含义,否则会导致接下来的内容理解困难。

为了协助大家理解这两个数组的含义,博主在这里举出一个例子。

这是一个字符串 \(S:\text{aabb}\)

为便于记录,我用一个二元组表示 \(S\) 的一个后缀极其起始位置,那么这个字符串的后缀所代表的二元组有:

\[\{\left(\text{aabb}, 1\right), \left(\text{abb}, 2\right), \left(\text{bb}, 3\right), \left(\text{b}, 4\right)\} \]

将所有的后缀按照字典序排序,即:

\[\{\left(\text{aabb}, 1\right), \left(\text{abb}, 2\right), \left(\text{b}, 4\right), \left(\text{bb}, 3\right)\} \]

回想之前的定义,\(sa_i\) 表示的是“排名为 \(i\) 的后缀的起始位置”。故 \(sa\) 数组为:\(\{1, 2, 4, 3\}\)\(rk_i\) 表示的是 “起始位置为 \(i\) 的后缀的排名”。故 \(rk\) 数组为 \(\{1, 2, 4, 3\}\)

emm 貌似这个例子举的不太好……

构造

倍增法构造 SA

直接找出所有后缀进行排序复杂度显然是 \(\mathcal O\left(n^2\right)\) 的,我们需要找到一种更快的方式构造后缀数组。

后缀自动机

构建 SAM

采用“增量法”,利用 \(S\) 的 SAM 构建出 \(S + c\) 的 SAM。

其中 \(S\) 是一个字符串,\(c\) 是一个字符,\(+\) 表示连接运算。

posted @ 2021-02-02 20:47  zimujun  阅读(215)  评论(1)    收藏  举报