初學回文自動機

2022-05-14 13:48:14 字數 1541 閱讀 3724

回文自動機,據說是解決回文問題的利器。

最近剛好遇到一道回文問題,加上正好閒著沒事幹,就來學了學。

感覺板子還是非常簡潔的,容易記憶。

與一般自動機類似,定義乙個節點的資訊。

一般包括表示長度\(fail\)指標後繼節點,當然視具體題目還要維護一些特殊資訊。

但也要注意回文自動機與一般自動機的區別,就是它的後繼\(x\)表示在當前串左右兩邊各加上乙個字元\(x\)(要保證每個節點對應的串是回文串)。

考慮回文分為奇回文和偶回文,因此回文自動機乙個特殊的地方就是,它有兩個根:奇根以及偶根。

分別設定它們的初始資訊:

節點編號

表示長度

\(fail\)指標

奇根

\(1\)

\(-1\)

奇根偶根皆可

偶根

\(0\)

\(0\)

奇根回文串和一般的字串相比要相對複雜,因此它的\(fail\)指標也不能和其他自動機一樣直接呼叫,而需要為它寫乙個專門的函式。

首先,乙個節點的\(fail\)指標所指向的,是該回文串的最長回文字尾所對應的節點。

但在具體使用時,由於回文串的後繼節點要求在串兩側各加上乙個字元,因此乙個節點的\(fail\)指標並不一定在任何時候都能實現擴充套件。

因此,我們需要不斷跳\(fail\),直至找到乙個合法的節點,滿足它可以向兩側擴充套件。

這一過程可以定義為乙個函式\(fail(x,id)\),具體實現詳見**。

插入乙個新的位置\(id\),首先我們要通過\(t=fail(lst,id)\)得到第乙個可擴充套件位置。

如果\(t\)已經有對應兒子,就不需要操作了;否則,我們新建乙個節點,節點長度就是\(t\)的長度加\(2\)(最後一次重複,回文串每次在串兩側各加上乙個字元),而\(fail\)指標就是繼續上跳,得到\(fail(fail[t],id)\)。

這一過程是非常簡短,也非常簡單的。

#include#define tp template#define ts template#define reg register

#define ri reg int

#define con const

#define ci con int&

#define i inline

#define w while

#define n 500000

using namespace std;

int n;char s[n+5];

class palindromeautomation

o[n+5];

i int fail(ri x,ci id) //根據實際情況找到合法的節點

public:

i palindromeautomation() //初始化節點資訊

i int ins(ci id)

}p;int main()

初學回文自動機

回文這個東西,有一些不錯的演算法。比如馬拉車演算法,就是一種非常優秀的演算法。我也學過一篇有關馬拉車的文章,非常的簡單易懂。但我們今天講的是比馬拉車更強的演算法 回文自動機。回文自動機和ac自動機有一些類似的地方,所以有興趣的同學可以看這篇文章來了解 ac自動機 好了,在開始今天的正文之前,我們得先...

回文自動機 初學

今天學習了一下回文自動機pam,發現比字尾自動機sam簡單好多啊。clj那個sam的ppt講的我頭昏腦漲的 叫你弱叫你弱 簡單寫一下免得自己忘記。幾個陣列 1.像各種自動機一樣,用ch x c 表示狀態x後新增字母c之後轉移到的狀態。2.同樣,用sum x 表示狀態x所含的回文串的個數 和sam一樣...

回文自動機

回文自動機,又叫回文樹,是由俄羅斯人 mikhailrubinchik於2014年夏發明的 這是一種比較新的資料結構,在原文中已有詳細介紹與 實現。回文樹其實不是嚴格的樹形結構,因為它有是兩棵樹,分別是偶數長度的回文樹和奇數長度的回文樹,樹中每個節點代表乙個回文串。為了方便,第一棵樹的根是乙個長度為...