Manacher演算法學習筆記

2022-09-20 07:03:10 字數 2173 閱讀 2469

manacher演算法是乙個求乙個字串中最長回文連續子串行的演算法

p3805 【模板】manacher 演算法

description:求最長回文子串的長度

solution:我們先引入乙個 \(o(n^2)\) 的做法,列舉每個字元為回文串的中心,嘗試向兩邊擴充套件,用擴充套件的最大長度更新答案。

為了下文描述方便,我們在原串中的每個字元兩邊加上 \(\tt\)​​​​ ,並在左邊加上 $ \tt $​,那麼字串 \(\tt\)​ 就會變成 \(\tt$​​​

新增字元的**:

inline void change() 

}}

sp7586 numofpal - number of palindromes

description:求回文子串個數

solution:manacher模板題,直接套模板即可。

code:

#include #include #define min(a,b) ((a)<(b)?(a):(b))

using namespace std;

const int n=1.1e7;

string a,s;

int p[n<<1|1];

int n,ans;

inline void change()

}}signed main()

p1659 [國家集訓隊]拉拉隊排練

description:求原串中所有長度位奇數的回文串降序排序後前 \(k\)​​ 個回文串長度的乘積

solution:先對原串跑一遍manacher,將每乙個回文串的長度記錄下來,但是這樣會 tle。

我們考慮優化,我們將每乙個 \(p_i\) 用桶存下來。因為可以延伸 \(p_i\) 個長度就一定可以延伸 \(p_i -2\) 個長度,每次加完 \(p_i\) 後將 \(p_i -2\) 的懂加上 \(1\) ,就可以優化將每乙個回文串的長度記錄下來這一步的複雜度,可以 ac 。

tips:因為本題所需要的回文串長度位奇數,我們在 change 函式中只要將原串兩邊不一樣的字元即可。

code:

#include #include #define min(a,b) ((a)<(b)?(a):(b))

typedef long long ll;

using namespace std;

const ll mod=19930726;

const int n=1e6+7;

string s;

int p[n],num[n];

ll k,ans=1;

int n;

inline ll mi(ll a,ll b,ll mod)

inline void change()

inline void manacher()

}}signed main()

else

}printf("%lld",ans);

return 0;

}

p4555 [國家集訓隊]最長雙回文串

description:求 \(s\) 的最長雙回文子串(定義見題面)

solution:我們在跑 manacher 時,再分別維護兩個陣列 \(l_i\)​​ 與 \(r_i\)​​ ,\(l_i\)​​ 表示以 \(i\)​​ 結尾的最長回文串長度,\(r_i\)​​ 表示以 \(i\)​​​ 開頭的最長回文串長度。跑完之後,我們遞推出所有以 \(\tt\)​​ 為斷點的 \(l_i\) 與 \(r_i\) 。每往後移一位,最長回文子串長度減 \(2\) 即可。

code:

#include #include #define min(a,b) ((a)<(b)?(a):(b))

using namespace std;

const int n=1e5+7;

string a,s="##";

int p[n<<1|1],l[n<<1|1],r[n<<1|1];

int n,ans;

inline void change()

l[i+p[i]-1]=max(l[i+p[i]-1],p[i]-1);

r[i-p[i]+1]=max(r[i-p[i]+1],p[i]-1);

}}signed main()

Manacher演算法 學習筆記

首先,強烈安利一篇文章,這篇文章對於 manacher 的講解本人感覺非常到位。傳送門相信大家都知道的乙個方法 列舉字串的每乙個位置作為回文子串的對稱中心,同時向左向右擴充套件,判斷是否相等,然後每次儲存之前求取的最大回文子串長度,時間複雜度為 o n 2 在列舉時,還需要考慮對奇數回文串和偶數回文...

演算法學習 manacher

沒有前置知識 解決的問題 大多數都和回文串有關 例如 字串中長度最長的回文串 演算法學習 請牢記這個目的 先來講樸素演算法 從1 n,對每個字元都從其自身開始,向兩邊遞推,如果左右兩邊字元相同,範圍 1,長度 2 這樣的複雜度是n 2的 而 manacher 的優化方式和 kmp 有所類似,都是利用...

Manacher演算法 學習總結

求乙個序列的最大回文子串,我們需要需要用到manacher演算法。其作用在於能夠在o n 的時間內求出最長回文子串,同時也能夠求出回文子串的個數。且時間效率高,十分簡潔。我們知道,回文子串分為奇數回文子串和偶數回文子串。由於兩種情況的處理較為麻煩,我們可以考慮在期間插入字元在簡化問題。例如例子 ab...