小A的回文串(manacher模板)
小A非常喜欢回文串,当然我们都知道回文串这种情况是非常特殊的。所以小A只想知道给定的一个字符串的最大回文子串是多少,但是小A对这个结果并不是非常满意。现在小A可以对这个字符串做一些改动,他可以把这个字符串最前面的某一段连续的字符(不改变顺序)移动到原先字符串的末尾。那么请问小A通过这样的操作之后(也可以选择不移动)能够得到最大回文子串的长度是多少。
输入描述:
一行一个字符串表示给定的字符串S一行一个字符串表示给定的字符串S
输出描述:
一行输出一个整数,表示通过这样的操作后可以得到最大回文子串的长度。
示例1
输入
dcbaabc
输出
7
说明
将前面的dcba移动到末尾变成abcdcba,这个字符串的最大回文子串就是它本身,长度为7
备注:
N表示字符串的长度,1≤N≤5000N表示字符串的长度,1≤N≤5000
可用manacher求最长回文子串长度
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
char s[N],s2[N],s1[N<<1];
int Len[N<<1];
int init(char *s2,char *s)
{
memset(s,0,sizeof(s));
int i,len=strlen(s2);
s[0]='@';
for(i=1;i<=2*len;i+=2)
{
s[i]='#';
s[i+1]=s2[i/2];
}
s[2*len+1]='#';
s[2*len+2]='$';
s[2*len+3]=0;
return 2*len+1;
}
int manacher(char *s,int len)
{
int p=0,ans=0,po=0;
for(int i=1;i<=len;i++)
{
if(p>i)
Len[i]=min(p-i,Len[2*po-i]);
else
Len[i]=1;
while(s[i-Len[i]]==s[i+Len[i]])
Len[i]++;
if(Len[i]+i>p)
{
p=Len[i]+i;
po=i;
}
ans=max(ans,Len[i]);
}
return ans-1;
}
int main()
{
while(cin>>s1)
{
int len=strlen(s1);
int maxlen=0;
for(int i=0;i<len;i++)
{
strcpy(s2,s1+i);
int len2=strlen(s2);
for(int j=0;j<i;j++)
s2[len2++]=s1[j];
int len1=init(s2,s);
int ans=manacher(s,len1);
maxlen=max(ans,maxlen);
}
cout<<maxlen<<'\n';
}
}