manacher(马拉车)
P3805 【模板】manacher
题目描述
给出一个只由小写英文字符 \(\texttt a,\texttt b,\texttt c,\ldots\texttt y,\texttt z\) 组成的字符串 \(S\) ,求 \(S\) 中最长回文串的长度 。
字符串长度为 \(n\)。
输入格式
一行小写英文字符 \(\texttt a,\texttt b,\texttt c,\cdots,\texttt y,\texttt z\) 组成的字符串 \(S\)。
输出格式
一个整数表示答案。
输入输出样例 #1
输入 #1
aaa
输出 #1
3
说明/提示
\(1\le n\le 1.1\times 10^7\)。
manacher的思想和z函数的加速盒子的思想是一样的,难点就是i的对称点的位置,i关与对称点的位置,就是i与r的差加上l,还有一点就是结果等于最长回文子串的长度减一

#include<iostream>
#include<string>
using namespace std;
const int N=3*1e7+5;
char s[N];
int d[N];
int main(){
string t;
cin>>t;
int k=0;
s[++k]='@',s[++k]='#';
for(int i=0;i<t.size();i++){
s[++k]=t[i];
s[++k]='#';
}
d[1]=1;
for(int i=2,l,r=1;i<=k;i++){
if(i<=r)d[i]=min(d[r-i+l],r-i+1);
while(s[i-d[i]]==s[i+d[i]])d[i]++;
if(i+d[i]-1>r)l=i-d[i]+1,r=i+d[i]-1;
}
int Max=-1;
for(int i=1;i<=k;i++)Max=max(Max,d[i]);
cout<<Max-1;
return 0;
}

浙公网安备 33010602011771号