• 后缀数组 & 后缀自动机


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

    后缀数组

    定义

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

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

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

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

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

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

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

    [{left( ext{aabb}, 1 ight), left( ext{abb}, 2 ight), left( ext{bb}, 3 ight), left( ext{b}, 4 ight)} ]

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

    [{left( ext{aabb}, 1 ight), left( ext{abb}, 2 ight), left( ext{b}, 4 ight), left( ext{bb}, 3 ight)} ]

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

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

    构造

    倍增法构造 SA

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

    后缀自动机

    构建 SAM

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

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

  • 相关阅读:
    vuex插件
    axios
    token登录验证
    mysql模糊查询
    Koa2+Mysql搭建简易博客
    正则匹配器
    编码
    Maven学习
    防止重复提交保证幂等的几种解决方案
    策略模式优化if-else
  • 原文地址:https://www.cnblogs.com/zimujun/p/14364135.html
Copyright © 2020-2023  润新知