• 「算法笔记」后缀树


    一、后缀树

    前置知识:字典树(Trie)

    后缀树:所有后缀 (S[isim n]\,(1leq ileq n)) 组成的 Trie 树。

    本质不同的子串个数可以达到 (mathcal{O}(n^2)) 级别,故节点数为 (mathcal{O}(n^2)),与枚举原串的每个子串等价。

    叶子节点只有不超过 (mathcal{O}(n)) 个,因此大部分节点都有且仅有一个孩子。

    (每分叉一次就会多一个叶子节点。一开始根节点算一个叶子节点,最后有不超过 (n) 个叶子节点,也就是多了不超过 (n-1) 个叶子节点。所以分叉的点数一定小于等于 (n-1)。那么其他的节点都是不分叉的,因此大部分节点都有且仅有一个孩子。)

    大部分节点都 只有一个孩子,考虑合并这样的链信息。即我们可以 缩掉仅有一个孩子的节点。就像这样:

    这样新的树中的节点数就变成 (mathcal{O}(n)) 的了。

    二、虚树

    1. 定义

    对于树 (T=(V,E)),给定关键点 (S⊆V),则可以定义 虚树 (T'=(V',E'))

    • 对于节点集合 (V'⊆V) ,使得 (uin V') 当且仅当 (uin S),或者 (∃x,yin S),使得 ( ext{LCA}(x,y)=u)。(即 (uin V') 当且仅当 (u) 为关键点或关键点的 ( ext{LCA})

    • 对于边集 (E')((u,v)in E'),当且仅当 (u,v∈V'),且 (u)(v)(V') 中深度最浅的祖先。

    与之前所说的联系:假如把所有叶子节点当做关键点的话,任意两个叶子节点的 ( ext{LCA}) 一定是分叉点,那么 (V') 就是所有的叶子节点以及分叉点组成的集合。

    (E') 其实就是把不分叉的链缩成一条边后的边集(即 (E') 中的一条边对应着一条没有子树的链)。这与我们之前说的「缩掉仅有一个孩子的节点」对应。

    2. 构建虚树

    考虑增量法,每次向虚树中增加一个关键点。

    按 DFS 序依次加入 (uin S),栈维护 右链(栈中相邻的两个节点在虚树上也是相邻的,并且栈中节点 DFS 序单调递增)。

    每加入一个关键点 (u),设上一个关键点为 (v),令 ( ext{LCA}(u,v)=w),将栈顶 (dep_x>dep_w) 的弹栈,加入 (w,u) 即为新的右链。

    (若栈顶存在 (dep_x=dep_w),则不加入 (w)。)

    在此过程中维护每个点的父节点,最终连边即可得到 (E′)

    (n=|S|)时间复杂度:(mathcal{O}(nlog n))

    三、SA 构建后缀树

    后缀数组 + 虚树。

    虚树的角度:

    • 按字典序 DFS,则节点排序相当于对后缀进行排序,亦即后缀数组。

    • 求出后缀数组后,即可用单调栈维护右链了。

    • ( ext{LCA}) 对应了两个节点的 ( ext{LCP}),因此可以 RMQ。

    时间复杂度:(mathcal{O}(nlog n))

    (不会 SAM 就可以用 SA+虚树 的方法啦)

    四、SAM 构建后缀树

    我们同样可以使用 后缀自动机 来构建后缀树:

    定理:后缀自动机的 parent 树为反串后缀树。

    正串的 SAM 维护的是原字符串所有前缀的后缀。那么同理,反串的 SAM,维护的就是所有后缀的前缀,可以得到所有后缀构成的 Trie,即后缀树。

    建出反串的 SAM 之后,就会直接得到后缀树。

    时间复杂度: (mathcal{O}(n|sum|))(mathcal{O}(nlog n))

    五、Ukkonen 算法

    Ukkonen 算法可以 (mathcal{O}(n)) 构建后缀树。

    (反正我不会 QAQ,可以康 这里

  • 相关阅读:
    [LeetCode] 811. Subdomain Visit Count
    [LeetCode] 993. Cousins in Binary Tree
    [LeetCode] 443. String Compression
    [LeetCode] 448. Find All Numbers Disappeared in an Array
    [LeetCode] 442. Find All Duplicates in an Array
    [LeetCode] 4. Median of Two Sorted Arrays
    [LeetCode] 983. Minimum Cost For Tickets
    [LeetCode] 322. Coin Change
    [LeetCode] 249. Group Shifted Strings
    [LeetCode] 1009. Complement of Base 10 Integer
  • 原文地址:https://www.cnblogs.com/maoyiting/p/14208703.html
Copyright © 2020-2023  润新知