初學回文自動機

2021-08-24 18:11:30 字數 2135 閱讀 4493

回文這個東西,有一些不錯的演算法。比如馬拉車演算法,就是一種非常優秀的演算法。

我也學過一篇有關馬拉車的文章,非常的簡單易懂。但我們今天講的是比馬拉車更強的演算法——回文自動機。

回文自動機和ac自動機有一些類似的地方,所以有興趣的同學可以看這篇文章來了解 ac自動機

好了,在開始今天的正文之前,我們得先定義一些陣列,以便更好的了解回文自動機。

fail[x]:x失配後跳轉到的不等於自身的最長字尾回文子串。(這個可能有點難看懂,但是參考ac自動機fail)

len[x]:以x為結尾的最長回文子串的長度。

cnt[x]:與以x結尾的最長回文子串相同的子串的個數

son[x][c]:編號為x的節點表示的回文串在兩邊新增字元c以後變成的回文串的編號

s[x]:第x次新增的字元(一開始設s[0] = -1,也可以是任意乙個在串s中不會出現的字元)。

定義完這些陣列後,我們就開始構建字尾自動機了。

首先我們建兩個空節點0和1,其中fa

il[0

]=1,

len[

1]=−

1 fai

l[0]

=1,l

en[1

]=−1

,這樣的設定對後面有用。

然後我們讀入乙個字元,找出以它為結尾的最長回文子串的長度。這段找的**如下:

ll get_fail(ll p,ll x)
那麼節點x的最長回文子串的長度為函式le

n[p]

+2l en

[p]+

2。因為我們看某個回文子串的最左端是否和新加入的字元一樣,如果一樣那就是我們要求的回文子串,如果不一樣,我們就跳轉到當前回文串的最長字尾回文子串,繼續匹配。是不是有點類似與ac自動機?

舉個例子,比如當前串為cbbabb,那麼最長的回文子串為bbabb,我們要加入字元a,那麼a先與bbabb左邊的字元(c)比較,發現不一樣,於是跳轉到bbabb的最長的字尾回文子串,也就是bb,繼續匹配。發現bb左邊的字元為a,和我們要加入的字元一樣,所以新加入的len就是le

n(bb

)+2=

4 len

(bb)

+2=4

,也就是子串abba。

然後我們再求出它的fail,也就是當前串abba的最長字尾回文子串,那麼我們拿bb繼續和a匹配,很遺憾不能匹配,所以會一路跳轉到0,而fa

il[0

]=1 fai

l[0]

=1

,所以到了點1,而le

n[1]

=−1 len

[1]=

−1

,帶到我們的ge

t get

_fail

f ai

l裡發現是s[

x−(−

1)−1

]=s[

x]s [x

−(−1

)−1]

=s[x

],也就意味著s[

x]=s

[x] s[x

]=s[

x]

所以它的最長字尾回文子串就是它自己b,所以我們把fail連到找到的點即可。fail[now]=son[get_fail(fail[cur],i)][s[i]-'a'];//cur=get_fail(last,i),s[i]是新加入的字元

#include

#define maxn 300010

#define ll long long

using

namespace

std;

ll read()

char s[maxn];

ll fail[maxn],son[maxn][26],len[maxn],cnt[maxn];

ll tot,last,cur,ans;

ll newnode(ll x)

ll get_fail(ll p,ll x)

int main()

cnt[last=son[cur][s[i]-'a']]++;

}for(i=tot-1;i>=0;i--)

return

0;}

給大家推薦這篇部落格,裡面有詳細的例子和**

初學回文自動機

回文自動機,據說是解決回文問題的利器。最近剛好遇到一道回文問題,加上正好閒著沒事幹,就來學了學。感覺板子還是非常簡潔的,容易記憶。與一般自動機類似,定義乙個節點的資訊。一般包括表示長度 fail 指標 後繼節點,當然視具體題目還要維護一些特殊資訊。但也要注意回文自動機與一般自動機的區別,就是它的後繼...

回文自動機 初學

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

回文自動機

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