基本子串结构
参考 xtq 2023 年论文《一类基础子串数据结构》
定义
- 出现次数:对于一个串 \(s\),\(\mathrm{occ}(t)\) 表示 \(t\) 在 \(s\) 中出现次数。
- 扩展串:\(\mathrm{ext(t)}\) 表示最长的包含 \(t\) 的串 \(t'\) 满足 \(\mathrm{occ(t')} = \mathrm{occ(t)}\),分别定义 \(\mathrm{Lext(t)}\) 和 \(\mathrm{Rext(t)}\) 表示以 \(t\) 为后 / 前缀的最长串 \(t'\) 满足 \(\mathrm{occ(t')} = \mathrm{occ(t)}\)。
- 等价类:两个字符串 \(x, y\) 等价当且仅当 \(\mathrm{ext(x)} = \mathrm{ext(y)}\),特别地,若 \(\mathrm{ext(t)} = t\),称 \(t\) 为所在等价类的代表元。记作 \(\mathrm{rep(A)}\)
容易证明 \(\mathrm{ext, Lext, Rext}\) 都是良定义的。我们现在想建立一种字符串结构,一个节点代表一个等价类,且可以实现在两边加字符链接到新的等价类。
压缩后缀自动机
考虑 SAM 上的一个节点,若其出度 > 1,则其右侧代表的内容不为 1,显然不能向右扩展;若表示一个后缀节点,往右边扩展就没东西了,也不能向右扩展。若 \(x\) 既不表示后缀,且出度 = 1,说明其每次出现后面加的字符都是一样的,则此时 \(x\) 可以和其唯一出边 \(y\) 合并,他们对应的 \(\mathrm{ext}\) 相同,重复这样的合并,就有:
- 压缩后缀自动机:将 SAM 上出度为 1 且不为后缀的节点与其出边合并,得到的自动机称为压缩后缀自动机。
上图为 abbab 及其反串的 SAM 及压缩 SAM。
你可以认为压缩 SAM 合并了所有的 \(\mathrm{ext}\) 等价类,分别得到了后缀的等价类和前缀的等价类,而且两个压缩 SAM 上的节点应该是一一对应的(\(\mathrm{ext}\) 和正反无关)因此:
- 对称压缩后缀自动机:将两个压缩 SAM 的对应节点结合,同时保留两个自动机上的转移,得到的结构为对称压缩后缀自动机。
将所有字符串按照第一次出现位置 \([l, r]\) 画在平面坐标系中,将所有在同一个等价类的字符串染上同一种颜色,得到的结构称为基本子串结构。
本质不同的块和压缩 SAM 上的节点一一对应,压缩 SAM 上的边可以看作横向或者竖向(分别表示反串 SAM 和 正串 SAM)的转移。
一些性质:
- 每一块是一个上端和左端对齐的阶梯形网格图。
- 每种本质不同的块 \(C\),出现了 \(\mathrm{occ(rep(C))}\) 次。
- 一块中的一行对应一个 endpos 等价类,一列对应一个 startpos 等价类。
- 定义等价类 \(C\) 的周长为行数与列数之和,则所有本质不同的块周长之和为 \(\mathcal{O(n)}\) 级别。