寫在前面
這里曾經有一篇很長的文章,由於太糞了被削除了。以下是全新的重置版本。
為什么下面有四個?四大天王有五個不也是常識嗎
「筆記」后綴數組
字符串 \(S\) 的后綴數組定義為兩個數組 \(sa,rk\)。
\(sa\) 儲存 \(S\) 的所有后綴 按字典序排序后的起始下標,滿足 \(S[sa_{i-1}:n]<S[sa_i:n]\)。
\(rk\) 儲存 \(S\) 的所有后綴的排名。
結合后綴的最長公共前綴,后綴數組可以用來處理許多復雜度字符串問題。
「筆記」后綴樹
對於一個字符串 \(S\),它的后綴樹是由其所有后綴 \(S[i:n]\,(1\le i\le n)\) 組成的,經過信息壓縮后的 Trie 樹。
后綴數組可以看作由后綴樹的所有葉結點按字典序排列得到的數組。
「筆記」后綴自動機
字符串 \(S\) 的后綴自動機 (suffix automaton, SAM) 是一個可以且盡可以接受 \(S\) 所有后綴的 最小的 DFA。
更形式化的定義:
- 字符串 \(S\) 的 SAM 是一張 DAWG(有向單詞無環圖)。節點被稱作 狀態,邊被稱作狀態間的 轉移。
- 存在一個起始節點,稱作 起始狀態。其它節點均可從起始節點出發到達。
- 每個 轉移 都標有一些字母。從一個節點出發的所有轉移均 不同。
- 存在數個 終止狀態。若從 \(t_0\) 出發,最終轉移到一個終止狀態,路徑上所有轉移連接起來一定是 \(S\) 的一個后綴。\(S\) 的每個后綴均可用一條 從起始節點到某個終止狀態 的路徑構成。
- 在所有滿足上述條件的 DFA 中,SAM 的節點數是最少的。
SAM 並不是一個典型的 DFA,在 DAWG 基礎上,除 \(t_0\) 外的每個狀態都被添加了一條 后綴鏈接。所有后綴鏈接組成了樹狀結構,這棵樹被稱為 parent 樹。
字符串 \(S\) 的 SAM 能包含 \(S\) 所有子串的信息。
SAM 將這些信息以高度壓縮的形式儲存,對於一個長度為 \(n\) 的字符串,它的 SAM 空間復雜度僅為 \(O(n)\),構建 SAM 的時間復雜度也僅為 \(O(n)\)。
「筆記」廣義后綴自動機
廣義 SAM 是一種用於維護 Trie 的子串信息的 SAM 的簡單變體。
將多個模式串插入到 Trie 后,即可使用廣義 SAM 維護多模式串的信息。這是廣義 SAM 最廣泛的應用之一,本文的重點也在於此。其基本思想是將多串的信息進行壓縮,使得 SAM 在仍滿足節點數最少的同時 包含所有子串的信息。此時 SAM 中的一個狀態可能同時代表多個串中相應的子串。