hdu2594 exkmp模板

原题: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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值