zoukankan      html  css  js  c++  java
  • 后缀数组

    基础结构

    后缀数组主要是有两部分共同构成,分别是 (tr[][]) 边和 (link[]) 边,

    后缀数组中,一个状态也代表一个字符串 , 注意了 ,因为后缀数组是个 DAG , 所以对于 (x) 点,认定其状态是从起点走到他自己的最长路径 (最长的字符串) ,而其他路径都是 (x) 字符串的后缀。

    (tr[x][i]) 和字典树含义一样,指的是 (x) 字符串接上 (i) 就是 (tr[x][i]) 字符串,同时顺着 (tr) 走可以走完一个字符串里所有的子串。

    (link[x]) 则代表当前后缀数组中 , (x) 字符串与其他存在于后缀数组的字符串的最长公共后缀 (也是一个字符串)。

    此外,还会记录一个 (len[x]) ,表示 (x) 状态的字符串的长度。

    构建方法

    对一个字符串构建后缀数组,总体上是将其所有的前缀从短到长依次都加入后缀数组中。

    而一步一步来看,实际上第i个前缀我们都只是把 (s[i]) 这个字符加入。

    我们假设已经正在加入 (c) 字符,上一个加入的点是 (last) ,这一次加入的点是 (nxt) ,很明显的是 (tr[last][c]=nxt)

    那么主要是找到 (link[nxt]) 了,我们设 (p=last) ,然后让 (p) 沿着 (link[p]) 往回跳:

    1. 如果 (tr[p][c]) 不存在,那么 (tr[p][c]) 可以直接连到 (nxt)

    2. 如果 (tr[p][c]) 存在,且 (len[tr[p][c]]=len[p]+1) ,则 (link[nxt]=tr[p][c]) 。终止操作。

    3. 如果 (tr[p][c]) 存在,但 (len[tr[p][c]]>len[p]+1) ,则进行下列操作:

    (q = tr[p][c]) ,新建一个 (clone) 点,完全将 (q) 点的 (link)(tr) 复制到 (clone) , 随后将 (link[q]) 指向 (clone) 并且顺着 (p) 回跳 , 把 (tr[p][c]=q) 的 改为 (tr[p][c]=clone) 。终止操作。

    可以发现,加入 (s[i]) 后,相当于加入了以 (i) 为结尾的前缀,随后 (link) 边会更新改变, (link) 边会形成一棵树,两点 LCA 为其最长公共后缀。

    未完待续

  • 相关阅读:
    DataSource
    Quality in the Test Automation Review Process and Design Review Template
    测试的面临的挑战
    【CSP-S2019模拟】11.11比赛总结
    【CSP-S2019模拟】【Comet OJ 模拟赛Day2T3】11.10比赛总结
    【CSP-S2019模拟】11.08比赛总结
    【Codeforces#599】简要题解
    【简单计数知识2】JZOJ6405. 【NOIP2019模拟11.04】c
    反演学习小计
    【CSP-S2019模拟】11.06比赛总结
  • 原文地址:https://www.cnblogs.com/redegg/p/12167318.html
Copyright © 2011-2022 走看看