manacher演算法用的還是不夠熟悉啊,被卡了好久。。。一會再寫個回文自動機的做法吧
清晰的回文自動機寫法
題意:若乙個回文串左半部分和有半部分分別為乙個回文串,則這個回文串被稱為雙倍回文串(這名字有點傻呀!)。求:給定乙個回文串,問最長的雙倍回文串有多長。
思路:由於雙倍回文串是建立在回文串的基礎上的,因此我們只需要對回文串動動手腳就行了
思考:若在manacher演算法處理好字串後再對回文串進行判定,由於演算法得到的p陣列是當前位置能向兩邊拓展的最長回文串,因此為了遍歷所有的回文串,必須將每個位置的p向下列舉;但這樣勢必造成一些重複列舉(其實不重要),比如當前回文串被包含在乙個更長的回文串,且在其右半部分,則顯然左半部分已經列舉過跟當前回文串一樣的回文串的p
為了捨棄這樣的重複的列舉,我們採取在構建p陣列的過程中進行雙倍回文串的判定
顯然,只有在演算法中i+p[i]>r即當前回文串右側突破的最遠右邊界,當前回文串才不是被列舉過的,也就是說它需要被判定一下是否為雙倍回文串。這樣,演算法複雜度就達到了o(n)
最後是判定過程,建議在草稿紙上隨便畫畫,然後細節就明了了
//#pragma comment(linker, "/stack:102400000,102400000")
#include "bits/stdc++.h"
#define pb push_back
#define ls l,m,now<<1
#define rs m+1,r,now<<1|1
#define hhh printf("hhh\n")
#define see(x) (cerr<<(#x)<<'='<<(x)inline int read()
const int maxn = 1e6+10;
const int mod = 1e9+7;
const double eps = 1e-9;
char s[maxn], s0[maxn];
int p[maxn];
int change()
}if(r}
return ans;
}int main()
洛谷 4287 雙倍回文
記字串ww的倒置為w rwr。例如 abcd r dcba abcd r dcba,abba r abba abba r abba。對字串x,如果xx滿足x r xxr x,則稱之為回文 例如abba是乙個回文,而abed不是。如果x能夠寫成的ww rww rwwrwwr形式,則稱它是乙個 雙倍回文...
洛谷P1802 5倍經驗日
現在樂鬥有活動了!每打乙個人可以獲得5倍經驗!absi2011卻無奈的看著那一些比他等級高的好友,想著能否把他們乾掉。乾掉能拿不少經驗的。現在absi2011拿出了x個迷你裝藥物 嗑藥打人可恥 準備開始與那些人打了 由於迷你裝乙個只能管一次,所以absi2011要謹慎的使用這些藥,悲劇的是,沒到達最...
洛谷 P1802 5倍經驗日
現在樂鬥有活動了!每打乙個人可以獲得5倍經驗!absi2011卻無奈的看著那一些比他等級高的好友,想著能否把他們乾掉。乾掉能拿不少經驗的。現在absi2011拿出了x個迷你裝藥物 嗑藥打人可恥 準備開始與那些人打了 由於迷你裝乙個只能管一次,所以absi2011要謹慎的使用這些藥,悲劇的是,沒到達最...