题目:传送门
套用的马拉车模板
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int p[3000005];
char str[3000005],s[3000005];
int n,mx,id,len;
void init()
{
int k=0;
str[k++] = '$';//字符串起始位置的特殊标志//字符串末不需要再加标志了 '\n'就可以代替了 //防溢出
for(int i=0;i<len;i++)
{
str[k++]='#';
str[k++]=s[i];
}
str[k++]='#';//最后一个字母后的符号
len=k;//字符串更新后的长度为k
}
int Manacher()
{
p[0] = 0;
int sum = 0;//记录最长回文串
mx = 0;
for(int i=1;i<len;i++)
{
if(i < mx) p[i] = min(mx - i, p[2 * id - i]);
else p[i] = 1;
/*p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;*/
while(str[i - p[i]]== str[i + p[i]]) //向两边扩展更新p[i] //因为预处理的设置,这里不必担心溢出问题
p[i]++;
if(p[i] + i > mx)//回文半径变大
{
mx = p[i] + i;//更新回文串能达到的末端位置
id = i;//更新回文串中心点
sum = max(sum, p[i]);//更新回文串的最长长度
}
}
return (sum - 1);
}
int main()
{
int cnt=1;
while(scanf("%s",s))
{
memset(str,0,sizeof(str));
if(s[0]=='E'&&s[1]=='N'&&s[2]=='D') break;
len = strlen(s);
init();
int temp = Manacher();
printf("Case %d: %d\n",cnt++,temp);
}
return 0;
}