SAM 字尾自動機

2022-05-03 13:57:16 字數 1946 閱讀 9008

好文**

luogup3804

**:

/*

定義.對給定字串s的字尾自動機是乙個最小化確定有限狀態自動機,它能夠接收字串s的所有字尾。

對給定字串s的字尾自動機是乙個最小化確定有限狀態自動機,它能夠接收字串s的所有字尾。

某一狀態t_0被稱作初始狀態,由它能夠到達其餘所有狀態。

自動機中的所有轉移——即有向邊——都被某種符號標記。從某一狀態出發的諸轉移必須擁有不同的標記。(另一方面,狀態轉移不能在任何字元上)。

乙個或多個狀態被標記為終止狀態。如果我們從初始狀態t_0經由任意路徑走到某一終止狀態,並順序寫出所有經過邊的標記,你得到的字串必然是s的某一字尾。

在符合上述諸條件的所有自動機中,字尾自動機有這最少的頂點數。(字尾自動機並不被要求擁有最少的邊數)

最簡性:它包含了所有s的子串的資訊。換言之,對於任意從初始狀態t_0出發的路徑,如果我們寫出所經過邊上的標記,形成的子串必須是s的子串。相應地,s的任意子串都對應一條從初始狀態t_0出發的路徑。

為了簡化說明,我們稱子串「匹配」了從初始狀態出發的路徑,如果該路徑上的邊標記組成了這一子串。相應地,我們稱任意路徑「匹配」某一子串,該子串由路徑中邊的標記組成。

字尾自動機的每個狀態都引領一條或多條從初始狀態出發的路徑。我們稱這個狀態有若干匹配這些路徑的方法。

引理1.兩個非空子串u和v(length(u)<=length(v))是終點等價的,當且僅當u在字串s中僅作為w的字尾出現。

引理2.考慮兩個非空子集u,w(length(u)<=length(w))。它們的終點集合不相交,或者endpos(w)是endpos(u)的子集。進一步地,這取決於u是否是w的字尾:

引理3.考慮乙個終點等價類。將該等價類中的子串按長度遞減排序。排序後的序列中,每個子串將比上乙個子串短,從而是上乙個字串的字尾。換句話說,某一終點等價類中的字串互為字尾,它們的長度依次取區間[x,y]內的所有數。

引理4.字尾鏈結組成了一棵以t_0為根的樹。

引理5.如果我們將所有合法的終點集合建成一棵樹(使得孩子是父母的子集),這棵樹將和字尾鏈結構成的樹相同。

狀態的數量:

由長度為n的字串s建立的字尾自動機的狀態個數不超過2n-1(對於n>=3)。

轉移的數量:

由長度為n的字串s建立的字尾自動機中,轉移的數量不超過3n-4(對於n>=3)。

定理1.dawg(s)中字尾鏈結組成的樹就是字尾樹st(rev(s))。

定理2.圖dawg(s)的邊都能用字尾樹st(rev(s))的擴充套件指標表示。另外,dawg(s)中的連續轉移就是st(rev(s))中反向的字尾指標。

定理3.使用字尾自動機dawg(s),我們可以用o(n)的時間構建字尾樹st(rev(s))。

定理4.使用字尾樹st(rev(s)),我們可以用o(n)的時間構建字尾自動機dawg(s)。

*/#include

#include

#include

#ifdef win32

#define ll "%i64d"

#else

#define ll "%lld"

#endif

const

int n=2e6+5

;typedef

long

long

ll;char

s[n];

inta[n],c[n],size[n],n;

ll ans=0

;inline

int max(int x,int

y)struct

suffixautomaton

}size[np]=1

; }

void

build()

void

calc()

printf(ll "\n

",ans);

}}sam;

intmain()

view code

字尾自動機SAM

原理詳細的可以看史上最通俗的字尾自動機詳解 想看懂還是要花很久。實現 include include using namespace std const int maxn 2000010 struct node nodes maxn int las 1 tot 1 char st maxn void...

SAM 字尾自動機

這玩意還真的好玄學,看了半天,也就看了個大概吧 確實很妙 總算理解了parent樹,但是關於sam的dag的性質的證明並沒有看太懂,也沒有特別明白。update 又看了一會,原來是自己把定義搞錯了,字尾自動機其實是在滿足以下條件的最簡狀態,主要是難構造,掌握構造 就好了,證明就不管了c。條件如下 摘...

字尾自動機sam學習小記

顧名思義,字尾自動機就是可以識別原串所有字尾的自動機,最後回到達葉子狀態,同時也可以識別所有連續子串。線性。由構造方法可知點數是線性的。構出sam後除了主鏈,即代表原串的鏈,其他的邊要麼就是構成了乙個新的字尾,要麼就是連線若干條構成了乙個新的字尾的邊,形成乙個類似樹的結構,所以邊也是線性的。很多性質...