原题:http://acm.hdu.edu.cn/showproblem.php?pid=2594
题解:给T和S串,求T的前缀和S的后缀最长相同的是多少,扩展kmp模板。定义
nxt[i] //表示 ti-tn子串与T的最长前缀
extend[i]//表示 si-sn子串与T的最长前缀
#include<cstdio>
#include<cstring>
#include<algorithm>
#define reg register
using namespace std;
const int N=5e5+10;
char s[N],t[N];
int ls,lt,nxt[N],extend[N];
//nxt[i] i-n与t的最长相等前缀
//extend[i] 表示si-sn中与t最长相等前缀
int main(){
freopen("hdu2594.in","r",stdin);
while(scanf("%s%s",t+1,s+1)!=EOF){
ls=strlen(s+1);lt=strlen(t+1);
nxt[1]=lt;int p=1,a=2;
while(p+1<=lt && t[p+1]==t[p]) p++;
nxt[2]=p-1;
for(reg int i=3,j,ti;i<=lt;i++){//预处理nxt数组表示
p=i+nxt[a]-1;//p为最长处理的终点
ti=i-a+1;//T串对应的位置
if(i+nxt[ti]-1<p) nxt[i]=nxt[ti];
else{
j=max(0,p-i+1);
while(i+j<=lt && t[i+j]==t[j+1]) j++;
nxt[i]=j;a=i;
}
}
p=1;a=1;
while(p<=ls && p<=lt && t[p]==s[p]) p++;
extend[1]=p-1;
for(reg int i=1,j,ti;i<=ls;i++){
p=a+extend[a]-1;ti=i-a+1;
if(i+nxt[ti]-1<p) extend[i]=nxt[ti];
else{
j=max(0,p-i+1);
while(i+j<=ls && j<=lt && s[i+j]==t[j+1]) j++;
extend[i]=j;a=i;
}
}
int ans=0;
for(reg int i=1;i<=ls;i++)
if(extend[i]>ans && extend[i]+i-1==ls) ans=extend[i];
if(ans==0) printf("%d\n",0);
else {
for(reg int i=1;i<=ans;i++) putchar(t[i]);
printf(" %d\n",ans);
}
}
return 0;
}