小小總結:
別忘了寫上初始化!
當字串下標從0
00開始時,pos
pospo
s初始化為−1-1
−1;若從1
11開始,則pos
pospo
s初始化為0
00;最終的pos
pospo
s代表最後乙個字元的下標(前者為n−1
n-1n−
1,後者為n
nn)。
根據本質不同的回文子串數量不超過∣s∣
|s|∣s
∣,回文樹節點數不超過n+2
n+2n+
2。節點0
00下面的回文串長度為偶數,節點1
11下面的回文串長度為奇數,而第乙個字元在加入時顯然只能構成奇數長度(長度為1
11)的回文子串,因此las
tlast
last
初始化為1
11比較好。
寫法與字尾自動機很像,但如果只有字尾插入的話節點編號是遞增的,統計end
po
sendpos
endpos
數(c nt
cntcn
t值)時無需進行計數排序。
若要將兩個字串連在一起建立回文自動機,則必須真的將兩個字串連線在一起,因為函式內部要呼叫這個連線後的字串(中間插入兩個不同且不使用的字元)。
#include "bits/stdc++.h"
#define hhh printf("hhh\n")
#define see(x) (cerr<<(#x)<<'='<<(x)inline int read()
const int maxn = 3e5+10;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const double eps = 1e-9;
char s[maxn];
int ch[maxn][26], fail[maxn], len[maxn], cnt[maxn], half[maxn];
int last, tot, pos;
void init()
void add(int c)
ch[p][c]=np; //ch[p][c]的更新一定要放最後,因為當p=1時,p=fail[p],會影響前面fail[np]的更新
}last=ch[p][c];
cnt[last]++;
}int main()
回文自動機
回文自動機,又叫回文樹,是由俄羅斯人 mikhailrubinchik於2014年夏發明的 這是一種比較新的資料結構,在原文中已有詳細介紹與 實現。回文樹其實不是嚴格的樹形結構,因為它有是兩棵樹,分別是偶數長度的回文樹和奇數長度的回文樹,樹中每個節點代表乙個回文串。為了方便,第一棵樹的根是乙個長度為...
回文自動機
乙個節點表示乙個回文串。tot 節點個數,即不同回文串的個數。兩棵樹,節點為0,1,所以最後計數時從2開始 n 新增的字元個數 last 新新增乙個字母後所形成的最長回文串表示的節點 nxt i c 節點i表示的回文串在兩邊新增字元c後變成的回文串編號 兒子 cnt i 節點i表示的本質不同的串的個...
回文自動機
回文樹 回文自動機 他的功能如下 求字首字串中的本質不同的回文串種類 求每個本質不同回文串的個數 以下標每個本質不同回文串包含的本質不同回文串種類 fail fail指標,類似於ac自動機,返回失配後與當前cnt 在最後統計後它可以表示形如以 num 表示以 len 表示以 s 存放新增的字元 n ...