1. manacher 马拉车
P3805 【模板】manacher 算法
思路
- 回文串长度有奇有偶,奇回文串有对称中心,那偶回文串呢,所以我们就在每两个字符串之间加一个#,再在整个串前面加一个 % ,这样奇偶串就可以用按一种方法处理了,比如abcd --> %a#b#c#d#
- 我们可以用O(n) 求出r数组,r[i]是以i为对称中心的回文串半径(长度包括i),令mx是回文串覆盖的最右边界的右边一位,p是覆盖最右边界的回文串的对称中心,这时我们要求r[i],暴力会TLE,当p<mx时,我们考虑r[i]可以从r[2 * p - i] 处已确认对称的部分转移过来,r[i]=min (mx-p,r[ 2 * p - i ]),之后继续尝试暴力向外拓展,看r[i]是否能增大
code
#include<bits/stdc++.h>
#define N 22000010
#define mod 998244353
#define int long long
using namespace std;
int n,ans;
int r[N];
char a[N];
template<class T> inline void read(T &x)
{
x=0;int g=1;char s=getchar();
for (;s<'0'||s>'9';s=getchar()) if (s=='-') g=-1;
for (;s>='0'&&s<='9';s=getchar()) x=(x<<1)+(x<<3)+(s^48);
x*=g;
}
signed main()
{
int i,j,op,x,y,z;
scanf("%s",a+1);
n=strlen(a+1);
for (i=n;i;i--) a[2*i]=a[i],a[2*i+1]='#';a[1]='#';a[0]='$';
int p=1,mx=1;
n=2*n+1;
for (i=1;i<=n;i++)
{
if (mx<=i) r[i]=1;
else r[i]=min(mx-i,r[2*p-i]);
while(a[i+r[i]]==a[i-r[i]]) r[i]++;
if (i+r[i]>mx)
{
mx=i+r[i];p=i;
}
ans=max(ans,r[i]);
}
printf("%lld\n",ans-1);
return 0;
}
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。