hdu3068 Manacher演算法 馬拉車演算法

2021-09-19 07:53:46 字數 1386 閱讀 1357

回文串水題

參考部落格:

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 為中心最遠能向右擴...