後綴自動機的應用

零.前置:

\(1.init:\)初始狀態。數組

\(2.end:\)結束狀態。數據結構

\(3.E:\)結束狀態\(end\)集合。spa

\(4.fa(s):parent\)樹上\(s\)的父親節點。排序

\(5.Reg(s):\)節點\(s\)能達到的\(end\)的集合。字符串

\(6.mx(s):\)節點\(s\)所表明的子串的最長長度。it

\(7.mn(s):\)節點\(s\)所表明的字串的最短長度。class

\(8.Right(s):\)狀態\(s\)出現的右端點集合。數據

\(9.ST(s):\)節點\(s\)能到達的狀態集合(點數)。查詢

一.後綴自動機的性質:

\(1.Right(s)\subset Right(fa(s))\)集合

\(2.mn(s) = mx(fa(s))+1\)

\(3.s\)所表明的全部串在母串中出現的次數和每次出現的右端點相同。

\(4.\)後綴自動機的\(parent\)樹是原串的反向前綴樹(把每一個前綴的反串插入到\(Trie\)樹中,而且把沒有分支的鏈合併)。

二.如何求拓撲序:

\(\exists e(u,v)\)\(mx(u) < mx(v)\);若\(fa(v)=u\)也能獲得\(mx(u) < mx(v)\)。因此將節點按照\(mx\)數組排序,能夠獲得拓撲序(基排\(O(n)\))。

三.如何求Right(s):

若只求大小,能夠按照逆拓撲序遞推;若是還須要求具體節點,須要平衡樹(啓發式合併)/可持久化平衡樹;若是須要動態維護\(|Reg(s)|\)(創建的同時維護),則須要一個數據結構,支持在有根樹上加邊刪邊,求子樹和,由於有根把子樹和轉化成鏈上加減,單點查詢而後\(LCT\)便可。

三.如何求ST(s):

逆拓撲序遞推,若求本質不一樣,則每一個狀態貢獻1;若相同算屢次,則每一個狀態貢獻\(|Right|\)次。

其餘應用:

\(1.\)求本質不一樣子串數量:\(\sum_{s}mx(s) - mn(s) + 1\)

\(2.\)求字符串的最小表示:先對\(S+S\)創建\(SAM\),而後在\(SAM\)上跑,每次貪心走字典序最小的出邊,走\(|S|\)步便可。

\(3.\)求兩個字符串的最長公共子串:對一個串創建\(SAM\),而後跑匹配,若是失配則跳\(fa\)

\(4.\)求後綴樹和後綴數組:把反串建\(SAM\)而後\(parent\)樹就是後綴樹,後綴樹上\(dfs\)獲得後綴數組。

\(5.\)字典序\(k\)小子串:求\(ST\)而後相似線段樹二分的去作。

\(6.\)求本質不一樣的子串總長:\(\sum_{s}\sum_{i=mn(s)}^{mx(s)}i\)

\({\color{red}{\text{咕}}}{\color{green}{\text{咕}}}{\color{blue}{\text{咕}}}{\color{brown}{\text{咕}}}{\color{gold}{\text{咕}}}{\color{grey}{\text{咕}}}{\color{purple}{\text{咕}}}{\color{pink}{\text{咕}}}{\color{red}{\text{咕}}}{\color{green}{\text{咕}}}{\color{blue}{\text{咕}}}{\color{brown}{\text{咕}}}{\color{gold}{\text{咕}}}{\color{grey}{\text{咕}}}{\color{purple}{\text{咕}}}{\color{pink}{\text{咕}}}\)

相關文章
相關標籤/搜索