p[i].以第i个字符为中心,的回文串最长扩展半径。//注意是每位插$后的字符串。
s 原串。
Ma 加$后的串
https://www.bilibili.com/video/av61197246?from=search&seid=3525358353451327352
在B站重新学了manacher 30理解,之前学过2次都忘了。。这次手敲一下。
为回文树打基础吧。
//KX
#include <cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
template<typename T>inline void rd(T&x){
x=0;int f=1;char ch=getchar();
while(ch<'0' ||ch>'9'){ if(ch=='-')f=-1; ch=getchar(); }
while(ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
x*=f;
}
typedef long long ll;
typedef double db;
const int M = 2e6+7;
#define ls o*2
#define rs o*2+1
#define pb push_back
char s[M];
char Ma[M*2];
int p[M],lMa;
void init()
{
int ct=0,len=strlen(s);
Ma[ct++]='$';Ma[ct++]='#';
for(int i=0;i<len;i++)
Ma[ct++]=s[i],Ma[ct++]='#';
Ma[ct]=0;
lMa=ct;
}
int manacher()
{
int len=lMa;
int id=0,mx=0;
int ma=0;
for(int i=0;i<len;i++)
{
if(i<mx)p[i]=min(p[2*id-i],mx-i);
else p[i]=1;
while(Ma[i+p[i]]==Ma[i-p[i]])p[i]++;
if(i+p[i]>mx)
mx=p[i]+i,id=i;
ma=max(p[i],ma);
}
return ma-1;
}
int main()
{
int t=0;
while(scanf("%s",s))
{
if(s[0]=='E')break;
// memset(Ma,0,sizeof(Ma));
init();
printf("Case %d: %d\n",++t,manacher());
}
return 0;
}