1811. Longest Common SubstringProblem code: LCS |
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 simple, for two 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 exactly two lines, each line consists of no more than 250000 lowercase letters, representing a string.
Output
The length of the longest common substring. If such string doesn't exist, print "0" instead.
Example
Input: alsdfkjfjkdsal fdjskalajfkdsla Output: 3
后缀自动机,
先构建第一个字符串的后缀自动机,再用第二个串与第一个串进行匹配,求出最大的公共子串
后缀自动机的相关blog
http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html (看这个blog才看懂的)
http://hi.baidu.com/myidea/item/142c5cd45901a51820e25039 (构图比较清楚)
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define Maxn 600010
char s[Maxn>>1];
struct suffix_automaton
{
char s[Maxn>>1];
int son[Maxn][27],step[Maxn],pre[Maxn];
int tot,last,len;
void Extend(char ch)
{
step[++tot]=step[last]+1;
int p=last, np=tot;
while (!son[p][ch])
{
son[p][ch]=np;
p=pre[p];
}
if (son[p][ch]==np) pre[np]=p;
else
{
int q=son[p][ch];
if (step[q]>step[p]+1)
{
step[++tot]=step[p]+1;
int nq=tot;
memcpy(son[nq],son[q],sizeof(son[q]));
pre[nq]=pre[q];
pre[q]=pre[np]=nq;
while (son[p][ch]==q)
{
son[p][ch]=nq;
p=pre[p];
}
}
else
pre[np]=q;
}
last=np;
}
void Build()
{
scanf("%s",s);
tot=last=0;
memset(son,0,sizeof(son));
memset(pre,0,sizeof(pre));
memset(step,0,sizeof(step));
len=strlen(s);
for (int i=0; i<len; i++)
Extend( s[i]-'a' );
}
}suf;
int main()
{
suf.Build();
int p=0,ans=0,sum=0;
scanf("%s",s);
int len=strlen(s);
for (int i=0; i<len; i++)
{
while (p && !suf.son[p][s[i]-'a'])
sum=suf.step[p=suf.pre[p]];
if (suf.son[p][s[i]-'a'])
{
sum++; p=suf.son[p][s[i]-'a'];
}
ans=max(ans,sum);
}
printf("%d\n",ans);
return 0;
}