先談我對字尾自動機的理解:
這不完全正確,它可以識別所有子串,於是也可以識別所有字尾
錯誤字尾自動機極限時間複雜度是o(n*2-1)比sa和s tree優
然後是字尾自動機可以幹什麼:
什麼?你說把他轉成lis跑nlogn?
既最長公共子串。
所以不是lcs最長公共子串行。
然後建出了sam就好了
建的過程不難
幾個定義
有乙個小問題:
1 首先建立儲存當前字元
x的結點
np,找到之前最後乙個建立的結點
(因為它一定滿足性質②
),然後就不斷按
pre指標跳
(直到跳到有
x兒子的結點為止).
2在這個過程當中我們會便利到沒有
x兒子的節點,沒有
x兒子的節點很好處理,直接將這個點連線過去即可
3 情況1:
step[p]+1=step[q]。這意味著我們
p的下乙個節點就是
q,在狀態
p和狀態
q中沒有多餘狀態存在,所以如果
p對於當前串可以接受字尾,那麼
q對於新串也可以接受字尾,所以
pre[np]=q
即可。
4 step[p]這時
,只要把q的
son邊和
pre邊都
copy到nq
上,然後把nq的
pre改為p,再
把q和np
的pre
都改為nq.
兩個重要性質
1.right集合。也就是我們所說的:step。
這個是什麼?這表示符合這種字串的集合。
2.parent 樹
也就是pre所構成的樹。
我們利用parent樹對siz合併
已達到求每個子串個數的目的。
通常並不需要真正建樹,只需要用桶排個序就好了。
#includeusing namespace std;
const int n=2e6+10;
char s[n];
int c[n]={};//乙個桶,計數排序
int a[n]={};//
int ans;
struct suffix_autosa[n];
int last,cnt;
void insert(char c)
cout<
}}sam;
int main()
字尾自動機SAM
原理詳細的可以看史上最通俗的字尾自動機詳解 想看懂還是要花很久。實現 include include using namespace std const int maxn 2000010 struct node nodes maxn int las 1 tot 1 char st maxn void...
SAM 字尾自動機
好文 luogup3804 定義.對給定字串s的字尾自動機是乙個最小化確定有限狀態自動機,它能夠接收字串s的所有字尾。對給定字串s的字尾自動機是乙個最小化確定有限狀態自動機,它能夠接收字串s的所有字尾。某一狀態t 0被稱作初始狀態,由它能夠到達其餘所有狀態。自動機中的所有轉移 即有向邊 都被某種符號...
SAM 字尾自動機
這玩意還真的好玄學,看了半天,也就看了個大概吧 確實很妙 總算理解了parent樹,但是關於sam的dag的性質的證明並沒有看太懂,也沒有特別明白。update 又看了一會,原來是自己把定義搞錯了,字尾自動機其實是在滿足以下條件的最簡狀態,主要是難構造,掌握構造 就好了,證明就不管了c。條件如下 摘...