回文串水題
參考部落格:
manacher演算法:在o(n)時間內找出最長的回文串的長度,
第一步在字串首加乙個@,然後在字串之間加#
例:aaabb 處理後:@#a#a#a#b#b#
abba 處理後:@#a#b#b#a#
p[i]陣列:表示i所在字元為中心的回文字串的最大半徑
j:i關於id的對稱的點
id:i+p[ i ]最大的點
mx:以id為中心的回文子串的的右邊界
思路:利用回文串對稱的特性,利用p[ j ]來判斷p[ i ],i無非兩種情況
1:i=mx-i,先令p[ i ]=mx-i,之後再向兩邊擴充套件判斷是否滿足回文的條件
如果p[ j ]2:i>=mx,先另p[ i ]=1,之後再向兩邊擴張判斷是否滿足回文的條件
**:
p[i]=mx>i?min(p[id*2-i],mx-i):1;
while(s[i+p[i]]==s[i-p[i]])
例子:
@ # a # a # b # c # c # b #
1 1 2 3 2 1 2 1 2 5 2 1 2 1
j id i mx
**:
#include#include#include#include#include#include#include#include#include#includeusing namespace std;
#define ll long long
const int mod=100000007;
const int inf=0x3f3f3f3f;
const ll inff=0x3f3f3f3f3f3f3f3f;
const ll n=20000005;
const ll m=50005;
#define mef(x) memset(x,-1,sizeof(x))
#define me0(x) memset(x,0,sizeof(x))
#define mei(x) memset(x,inf,sizeof(x))
char str[n];
int p[n];
void manacher(char *s,int len)
if(i+p[i]>id+p[id])
}}int main()
str[0]='@';
len=len*2+2;
manacher(str,len);
int ans=0;
for(int i=0;iprintf("%d\n",ans);
return 0;
}
HDU3068 manacher演算法 最長回文串
求最長的回文串。有一次用dp求過一次。我們都知道求回文串可以依賴於暴力的方法 以某點為重心,暴力的比唄 manacher方法的思想在於利用對稱性來減少暴力運算,從而提高效率。從左到右遍歷字元,記錄最大的 回文串的右界 記當時的 字元位置為i 分兩種情況 1 當前遍歷字元x在 右界右邊。這時候無法利用...
hdu 3068 最長回文 manacher
給出乙個只由小寫英文本元a,b,c y,z組成的字串s,求s中最長回文串的長度.回文就是正反讀都是一樣的字串,如aba,abba等 輸入有多組case,不超過120組,每組輸入為一行小寫英文本元a,b,c y,z組成的字串s 兩組case之間由空行隔開 該空行不用處理 字串長度len 110000 ...
hdu 3068 最長回文 manacher
好的講解manacher演算法的文章,並茂。題意 求給定串的最長回文子串 2009 多校題目 分析 列舉每個點向左向右擴充套件,看最遠能擴充套件到哪兒 但是普通的列舉是 n 2的,肯定超時。現在我們想 kmp或擴充套件 kmp一樣,給字串定義乙個 nex陣列,nex i 表示以i 為中心最遠能向右擴...