最长回文串 拓展kmp

#include
#include
#include
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 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 {
if(nextb[i-k]+i else
{
j=nexta[k]+k-i;
if(j<0)j=0;
while(b[j]==a[j+i]&&b[j]&&j+i nexta[i]=j;
k=i;
}
}
}
void rev(char a,int len)
{
char t;
for(int i=0;i }
void solve(char a,int len)
{
if(len<=ans||len<2)return ;
int mid=len>>1;
int i;
for(i=mid;i b[i-mid]=0;
rev(a,len);
kmp2(a,b,nexta1,nextb,len);
rev(a,len);
for(i=0;i b[i]=0;
kmp2(a,b,nexta2,nextb,len);
nexta1[len]=nexta2[len]=0;
for(i=0;i {
if(nexta2[i]>=(mid-i)/2)
{
int x=mid-i+2
nexta1[len-i];
if(x>ans)ans=x;
}
}
for(i=mid;i {
if(nexta1[len-i]>=(i-mid)/2)
{
int x=i-mid+2
nexta2[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)