1. 程式人生 > 其它 >P3805 【模板】manacher演算法

P3805 【模板】manacher演算法

技術標籤:P3805Manacher模板

文章目錄

R e s u l t Result Result

...


H y p e r l i n k Hyperlink Hyperlink

https://www.luogu.com.cn/problem/P3805


D e s c r i p t i o n Description Description

給定一個長度為 n n n的字串,求其最長迴文子串

資料範圍: n ≤ 1.1 × 1 0 7 n\leq 1.1\times 10^7 n1.1×107


S o l u t i o n Solution Solution

在串的最前面新增一個字元 ∼ \sim
在末尾新增一個換行符
中間新增一手 ∣ |
將串 A B C C B A ABCCBA ABCCBA轉化成 ∼ ∣ A ∣ B ∣ C ∣ C ∣ B ∣ A ∣ \sim|A|B|C|C|B|A|

ABCCBA

接著設 m i d mid mid表示當前處理出最大回文串的中心, m x mx mx表示此串最遠的拓展中心, p i p_i pi表示以 i i i為迴文中心的最長半徑

每次只需令 p i = m i n { m x − i , p 2 m i d − i } p_i=min\{mx-i,p_{2mid-i}\} pi=min{mxi,p2midi}然後暴力匹配即可

時間複雜度: O ( n ) O(n) O(n)


C o d e Code Code

#include<cstdio>
#include<cstring>
#include
<algorithm>
#define LL long long #define N 22000010 using namespace std;char s[N],news[N]; int n,newn,p[N]; inline void Init() { news[0]='~';news[1]='|';newn=2; for(register int i=0;i<n;i++) news[newn++]=s[i],news[newn++]='|'; news[newn]=10;return; } inline int Manacher() { int mid=1,mx=1,ans=0; for(register int i=1;i<newn;i++) { if(i<mx) p[i]=min(mx-i,p[2*mid-i]);else p[i]=1; while(news[i-p[i]]==news[i+p[i]]) p[i]++; if(mx<i+p[i]) { mid=i; mx=i+p[i]; } ans=max(ans,p[i]-1); } return ans; } signed main() { scanf("%s",s); n=strlen(s);Init(); printf("%d\n",Manacher()); }