回文樹總結

2022-04-28 22:27:20 字數 1468 閱讀 1030

寫馬拉車還不如寫回文樹。

---by 陳菊開

原**請轉2023年集訓隊**《回文樹及其應用》by翁文濤

我感覺回文樹/回文自動機相較於字尾自動機還是要好理解一點的(像我這種菜雞到現在還不是很懂sam)。

回文樹,顧名思義,就是要把乙個串的所有回文子串丟到一棵樹上。那要向sam一樣記錄個什麼鬼\(endpos\)啥的嗎?不用。只需要對每一種本質不同的回文子串建乙個節點就可以了。(「本質不同」指的是長度不同或是內容不同,與出現位置無關)

對於乙個節點,也就是乙個回文子串,我們需要對他記錄以下資訊:

\(len\):就是這個回文子串的長度

\(tr_c\):在這個回文串的兩邊分別加上乙個字元\(c\)後形成的回文串

\(fail\):這個回文串的最長回文字尾

為了方便表示回文樹的結構,我們額外定義了兩個根節點,\(odd\)和\(even\)。其中\(even\)是乙個長度為\(0\)的空串,\(odd\)是乙個不存在的長度為\(-1\)的串。

這樣的定義可以讓任何乙個回文子串都存在\(fail\)。比如說,串\(babbab\)的\(fail\)是\(bab\),串\(aba\)的\(fail\)是\(a\),串\(aa\)的\(fail\)是\(even\),串\(b\)的\(fail\)是\(odd\)。特別的,定義\(even\)的\(fail\)是\(odd\),\(odd\)的\(fail\)還是\(odd\)。

可以通過數學歸納法證明:乙個串中本質不同的回文子串的個數是\(o(n)\)級別的。

考慮在原串\(s\)後面插入乙個字元\(c\),這樣就可能新形成若干以這個新字元\(c\)結尾的回文字尾。由於結束位置相同,所以較短的回文字尾也是較長的回文字尾的字尾。其中必然存在乙個長度最長的回文字尾,所有其他的回文字尾都是他的字尾。

那麼這時候考慮乙個回文串的基本性質:字尾等於字首(長度相同的情況下)。

所以既然所有其他回文字尾都是最長回文字尾的字尾,那麼他們就也是這個最長回文字尾的字首。

既然是字首,那麼就說明他們在之前的位置已經出現過了。

由此可以說明,在加入乙個字元後,至多增加乙個本質不同的回文子串。所以數量是\(o(n)\)級別的。

這樣你已經知道了回文樹/回文自動機的基本原理。但這還不夠,因為你還得知道——

這樣寫

struct palindromic_tree

void extend(int c,int n,char *s)

last=tr[v][c];

}};

其中\(0\)表示\(even\),\(1\)表示\(odd\)。

是不是特別好寫?

這個嘛。。。

你可以求以某乙個位置結尾的最長回文字尾的長度(就是\(len_\))

你把字尾樹建出來再維護乙個\(dep\)就可以知道有多少個回文串(不同位置的算不同的)

等等一些騷操作

鑑於我題做的還不是很多所以以後再補(也可能是永遠都不會補了)

回文樹總結

首先,回文自動機就是回文樹。不愧是 texttt 在 csp 模擬賽裡面考 pam 然後全場就我切了 求乙個由小寫字母 a z 構成的串的本質不同的回文子串數量。首先考慮把每乙個子串列舉出來,然後判斷是不是回文串再把它 hash 進 map 或者是 hash table 裡面。複雜度 theta n...

回文樹(自動機) 練習和總結

回文樹是一種強大的回文字串處理演算法,他的構造過程實際上和kmp多少有些相似,這裡講的很是仔細。下面摘錄幾個例題。ural 1960 palindromes and super abilities 每次加乙個新節點,說明了有乙個新的回文串產生。這個感覺真的很重要啊 我們在自動機裡記錄一下就好 ura...

回文樹 模板

類似ac自動機,樹裡面每個節點代表主串的乙個回文子串,且每個回文子串都不同 主要功能 1.求串s字首0 i內本質不同回文串的個數 兩個串長度不同或者長度相同且至少有乙個字元不同便是本質不同 2.求串s內每乙個本質不同回文串出現的次數 3.求串s內回文串的個數 4.求以下標i結尾的回文串的個數 con...