#include
#include<stdio.h>
#include<string.h>
using namespace std;
#define Max 110005
#define inf 10000000
char a[Max];//主串
char b[Max];//模式串
int nextb[Max],nexta1[Max],nexta2[Max],ans;
void kmp1(char *b,int *nextb){
int i,j,k,t;
i=0;
while(b[i]==b[i+1])i++;
nextb[1]=i;
k=1;
for(i=2;b[i];i++){
if(nextb[i-k]+i<nextb[k]+k)nextb[i]=nextb[i-k];
else{
j=nextb[k]+k-i;
if(j<0)j=0;
while(b[j]==b[j+i]&&b[i+j])j++;
nextb[i]=j;
k=i;
}
}
}
void kmp2(char *a,char *b,int *nexta,int *nextb,int len)
{
kmp1(b,nextb);
int i,j,k;
i=0;
while(a[i]==b[i])i++;
nexta[0]=i;
k=0;
for(i=1;i<len;i++)
{
if(nextb[i-k]+i<nexta[k]+k) nexta[i]=nextb[i-k];
else
{
j=nexta[k]+k-i;
if(j<0)j=0;
while(b[j]==a[j+i]&&b[j]&&j+i<len)j++;
nexta[i]=j;
k=i;
}
}
}
void rev(char a,int len)
{
char t;
for(int i=0;i<len/2;i++)t=a[i],a[i]=a[len-1-i],a[len-1-i]=t;
}
void solve(char a,int len)
{
if(len<=ans||len<2)return ;
int mid=len>>1;
int i;
for(i=mid;i<len;i++) b[i-mid]=a[i];
b[i-mid]=0;
rev(a,len);
kmp2(a,b,nexta1,nextb,len);
rev(a,len);
for(i=0;i<mid;i++) b[i]=a[mid-i-1];
b[i]=0;
kmp2(a,b,nexta2,nextb,len);
nexta1[len]=nexta2[len]=0;
for(i=0;i<mid;i++)
{
if(nexta2[i]>=(mid-i)/2)
{
int x=mid-i+2nexta1[len-i];
if(x>ans)ans=x;
}
}
for(i=mid;i<len;i++)
{
if(nexta1[len-i]>=(i-mid)/2)
{
int x=i-mid+2nexta2[i];
if(x>ans)ans=x;
}
}
solve(a, mid-1);
solve(a + mid, len-mid);
}
int main()
{
while(scanf("%s",&a)!=EOF)
{
ans=1;
solve(a,strlen(a));
printf("%d\n",ans);
}
}
最长回文串 拓展kmp
最新推荐文章于 2021-02-12 04:25:03 发布