首页 > 学院 > 开发设计 > 正文

SPOJ LCS2 Longest Common Substring II

2019-11-08 01:01:26
字体:
来源:转载
供稿:网友

A string is finite sequence of characters over a non-empty finite set Σ.

In this PRoblem, Σ is the set of lowercase letters.

Substring, also called factor, is a consecutive sequence of characters occurrences at least once in a string.

Now your task is a bit harder, for some given strings, find the length of the longest common substring of them.

Here common substring means a substring of two or more strings.

Input

The input contains at most 10 lines, each line consists of no more than 100000 lowercase letters, representing a string.

Output

The length of the longest common substring. If such string doesn't exist, print "0" instead.

Example

Input:alsdfkjfjkdsalfdjskalajfkdslaaaaajfaaaaOutput:2

Notice: new testcases added

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

后缀自动机~

推荐两篇博客:那篇俄罗斯文章的翻译,一篇神奇的双语总结~

以及陈老师的PPT~

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define maxn 200001int len,tot,cnt,s[maxn],l[maxn],cl[maxn],mn[maxn],fa[maxn],to[maxn][26],v[maxn],ans;char ch[100001];struct sam{	int p,q,np,nq,la;	sam(){		cnt=++la;	}		void ext(int u)	{		p=la;la=np=++cnt;l[np]=l[p]+1;		for(;p && !to[p][u];p=fa[p]) to[p][u]=np;		if(!p) fa[np]=1;		else		{			q=to[p][u];			if(l[p]+1==l[q]) fa[np]=q;			else			{				nq=++cnt;l[nq]=l[p]+1;				memcpy(to[nq],to[q],sizeof(to[q]));				fa[nq]=fa[q];fa[np]=fa[q]=nq;				for(;to[p][u]==q;p=fa[p]) to[p][u]=nq;			}		}	}		void build()	{		scanf("%s",ch);		len=strlen(ch);		for(int i=0;i<len;i++) ext(ch[i]-'a');	}		bool pre()	{		if(scanf("%s",ch)==EOF) return 0;		len=strlen(ch);		memset(cl,0,sizeof(cl));		int tmp=0;		for(int p=1,i=0;i<len;i++)		{			int c=ch[i]-'a';			if(to[p][c]) p=to[p][c],tmp++;			else			{				while(p && !to[p][c]) p=fa[p];				if(!p) p=1,tmp=0;				else tmp=l[p]+1,p=to[p][c];			}			cl[p]=max(cl[p],tmp);		}		for(int i=cnt;i;i--)		{			int t=s[i];			mn[t]=min(mn[t],cl[t]);			if(fa[t] && cl[t]) cl[fa[t]]=l[fa[t]]; 		}		return 1;	}}sam;int main(){	sam.build();	for(int i=1;i<=cnt;i++) mn[i]=l[i],v[l[i]]++;	for(int i=1;i<=len;i++) v[i]+=v[i-1];	for(int i=1;i<=cnt;i++) s[v[l[i]]--]=i;	while(sam.pre());	for(int i=1;i<=cnt;i++) ans=max(ans,mn[i]);	printf("%d/n",ans);	return 0;}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表