與manacher+字尾自動機倍增匹配相比快太多。
manacher+sam寫法
以上是回文自動機的速度
以上是manacher+sam的速度。
感受一下。。(受個人lj**的常數影響)
回文自動機是乙個類字典樹,構造方式又類似於ac自動機。其每個結點就代表了乙個回文串(這與字尾自動機乙個結點代表多個字串不同),由於有單數長度回文串後偶數長度回文串的影響,所以我們這個樹有兩個根分別代表的長度為0和-1,但最後所以無法回跳時的fail 都指向長度為0的結點。在此後堆每個結點對於他的父親都長度+=2
回跳指標代表的意義是結點字尾中長度最長的那乙個回文串(最後乙個位置的字元相同)。在我們構造的時候,加入乙個字元t考慮以上乙個到達的結點(字串中的上乙個)las跑fail,找到第乙個能夠容下t成為回文的位置(也就是找到乙個回文 結點,其前面那個字元為t)。然後如果這個位置cur沒有 nt[cnr][t]那麼我們又找到了乙個本質不同的回文。
加入新結點的回跳指標就很像ac自動機 ,在他找到的結點cur這裡的fail[cur]裡再跑fail找到乙個結點能夠與t匹配。我們顯而易見的發現他長度變短,但最後乙個字元為t。然後將fail[新結點]設定為nt[fail[cur]找到的結點][t]。
最後的cnt可見對於乙個結點x其fail[x]一定為其子回文串,在構造完後倒序往前加一遍即可。
極弱的code:
#include#includeusing namespace std;const int maxn = 300005;
int tot,pos,las,nt[maxn][27],fail[maxn];
int s[maxn],len[maxn],cnt[maxn],fa[maxn];
int push(int ll)
void init()
int getfail(int x)
void extend(int t)
las = nt[cur][t];
cnt[las]++;
}char ss[maxn];
int main()
APIO2014 回文串 (回文自動機裸題)
傳送門 沒看過題目的可以先看一下,題目要我們求的是回文串長度len 出現次數的最大值。很符合回文自動機的性質的題目,可以用sam manacher做,也不難,但是對回文自動機來說就是裸題。1,本質不同回文子串長度len陣列。2,出現次數可以用拓撲之後向前逆推求 upd 其實並不需要拓撲,因為回文數的...
省選專練之後綴自動機APIO2014回文串
本來是個回文自動機模板題 但是也可以用字尾自動機ac掉 先跑manacher 這可以識別所有的回文串 然後放進自動機裡暴力跑就是了 include include include include includeusing namespace std typedef int int define ll...
APIO 2014 序列分割
題目鏈結 演算法 首先 我們發現將一段序列切成若干段所獲得的收益與順序無關 於是我們可以用fi,j表示切i次 前j個數的最大收益 令sumi表示ai的字首和 顯然 fi,j max 斜率優化即可 此題記憶體限制較緊 可以使用滾動陣列優化空間複雜度 時間複雜度 o nk includeusing na...