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...