manacher演算法 回文串計算的高效演算法

2022-09-04 07:51:08 字數 1328 閱讀 8520

進入正題,manacher演算法是乙個高效的計算回文串的演算法,回文串如果不知道可以給出乙個例子:「 noon 」,這樣應該就很清晰了;

其實這個演算法雖然名字長,但是實際**很短,而且理解起來並不難。。。(連我這種蒟蒻都懂了)

這裡給出模板題

給出乙個只由小寫英文本元a,b,c...y,z組成的字串s,求s中最長回文串的長度.

字串長度為n

一行小寫英文本元a,b,c...y,z組成的字串s

乙個整數表示答案

其中n的範圍為11000000,很顯然,只能是o(n)的複雜度,但是為何複雜度這麼優秀,這裡在講完演算法之後會簡述。

定理:

解釋:

上面的原理畢竟太過幹,只是純理論,所以製圖說明;

比如說這個區間是乙個大回文串,我們我們用r保留其有邊界,那麼l就可以根據中點座標公式變形得到mid*2 - r,所以我們只保留右邊界 r 即可。

那麼可以看見,如果我們以 i 為這段區間中乙個回文串的中心,那麼,與它對稱的回文串中心就可以求出(根據中點公式,得2*mid - i ,與上面相同);

那麼我們就可以根據定理來繼承左邊回文串的半徑,但是如果左邊這個回文串有超過區間的部分怎麼辦?

這裡就用到我們所說的取min了,將左邊回文串半徑和r - i相比取min,這裡就得到了 i 的乙個半徑,但這個半徑一定小於或等於真實半徑,所以還需暴力列舉;

這裡就可見manachar演算法的核心操作了,就是列舉回文串中心,然後繼承半徑以來減少列舉的次數;

我們用p[ i ]表示以點 i 為中心的回文串的半徑,r記錄回文串到達的最右邊的座標,mid隨之更新,記錄這個回文串的中心;

code

#include#define maxn 22000007

using

namespace

std;

char

dat[maxn];

int p[maxn],r,cnt=1

,mid,ans;

void

scan()

//其實與讀入優化沒差啦

}//自定義讀入

intmain()

printf(

"%d\n

",ans-1);//

這個減一可以自己模擬一下,數學推了話好麻煩的說

}

這就是manachar演算法的簡述了,當然這裡解釋一下為什麼複雜度為o(n):

我感覺這和kmp複雜度有些類似,因為這裡因為繼承的緣故,所以每個點更新次數較少,然後均攤到每個迴圈,那麼複雜度就變成了o(n)了;

(回文串)Manacher演算法

標籤 acm 回文串 manacher 輸入乙個字串,求出其中最大的回文子串。子串的含義是 在原串中連續出現的字串片段。回文的含義是 正著看和倒著看相同,如abba和yyxyy。這裡介紹o n 回文子串 manacher 演算法 演算法基本要點 首先用乙個非常巧妙的方式,將所有可能的奇數 偶數長度的...

(Manacher)演算法 O n 回文子串

資料 網路 參見 問題描述 輸入乙個字串,求出其中最大的回文子串。子串的含義是 在原串中連續出現的字串片段。回文的含義是 正著看和倒著看相同,如abba和yyxyy。解析 這裡介紹o n 回文子串 manacher 演算法 演算法基本要點 首先用乙個非常巧妙的方式,將所有可能的奇數 偶數長度的回文子...

O n 求回文串 manacher演算法

p id 2 i 代表的是關於i關於id對稱的點j,陣列p i 1代表插入字元後一i問對稱的回文串的長度 資料 網路 參見 問題描述 輸入乙個字串,求出其中最大的回文子串。子串的含義是 在原串中連續出現的字串片段。回文的含義是 正著看和倒著看相同,如abba和yyxyy。解析 這裡介紹o n 回文子...