省選演算法學習 回文自動機 回文樹

2022-03-07 05:13:41 字數 1426 閱讀 9983

首先你得會manacher,並理解manacher為什麼是對的(不用理解為什麼它是$o(n)$,這個大概記住就好了,不過理解了更方便做$pam$的題)

回文自動機(palindrome automaton),是一類有限狀態自動機,能識別乙個字串的所有回文子串

它可簡化構建出回文樹

網上資料很多,不拿出來一步步說了,說一下陣列意義、放個板子

$len[u]$表示節點$u$代表的回文串的長度

$ch[u][c]$代表在$u$的回文串兩端新增字元$c$得到的新回文串節點

$fail[u]$表示節點$u$的回文串的最長的回文字尾所在的節點

char s[300010];

int n;

//這個板子裡面的num表示當前節點的回文串出現了幾遍

namespace pam

void init()

inline int getfail(int cur,int pos)

void insert(int x)

num[last=ch[cur][c]]++;

}}

fail初始化的時候,如果多組資料並且在newnode裡面初始化資訊,那麼在init的時候記得把fail放到newnode後面

插入的時候函式傳進去的是位置

newnode是len[cur]+2不是+1

首先顯然可以統計這個節點的回文串出現次數

統計次數的時候還要加上$fail$樹上子樹內的所有節點的出現次數

對於一類回文串擁有某個和其$fail$樹有關的性質的題目,可以記錄乙個$trans$,和跳$fail$一樣跳,最後用$bfs$來做$dp$或者遞推

這個問題是問可以把乙個字串分解成最少多少個回文串

解決的方法:

考慮乙個顯然的$dp$:$dp[i]=dp[j-1]+1 (s[i...j]=palindrome)$

記錄乙個$anc[u]$

如果$len[u]-len[fail[u]]==len[fail[u]]-len[fail[fail[u]]]$,那麼$anc[u]=anc[fail[u]]$

否則$anc[u]=u$

對於$u$的所有跳上去的$anc$集合$s$,我們發現,這個集合中的元素構成乙個等差數列,相鄰的兩項差代表一種從當前點前面遞推到當前點的回文串長度

對於每個回文樹節點記錄$tmp[u]=min(tmp[i-len[anc[u]],tmp[fail[u]])$,然後用這個$tmp[u]+1$來更新當前節點的$dp$,然後$u=fail[anc[u]]$往上跳,直到到達根

證明網上有**,這裡放個**

inline void insert(int x)

last=ch[cur][c];

for(cur=ch[cur][c];cur>1;cur=fail[anc[cur]])

}

回文樹(回文自動機) 筆記

回文樹詳解1 what is palindromic auto machine?回文自動機,又叫回文樹,是由俄羅斯人 mikhailrubinchik於2014年夏發明的 這是一種比較新的資料結構,在原文中已有詳細介紹與 實現。回文樹其實不是嚴格的樹形結構,因為它有是兩棵樹,分別是偶數長度的回文樹和...

馬拉車演算法 回文樹(回文自動機)

下標 i 0 是 原字串插入 字元變為 奇數長度,結尾位置新增 維持奇數字元個數 arr字串 經過處理的字串 eg fabbac f a b b a c 輔助陣列p p i 表示 arr字串 在 i 位置的最長回文半徑 兩個關係 最長回文串 是原串 fabbac 的最長回文串長度 p i 1 以 i...

回文自動機

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