您的位置:首页 > 其它

后缀自动机(SAM) :SPOJ LCS - Longest Common Substring

2016-02-24 22:52 253 查看

LCS - Longest Common Substring

no tags

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

  这题就是求最长公共子串,于是我直接套用了SAM。


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN=1000010;
struct SAM{
int fa[MAXN],ch[MAXN][27],len[MAXN],cnt,last;
void Init()
{
last=cnt=1;
}
void Insert(int c)
{
int p=last,np=last=++cnt;
len[np]=len[p]+1;
while(!ch[p][c]&&p)
ch[p][c]=np,p=fa[p];
if(!p)fa[np]=1;
else{
int q=ch[p][c];
if(len[q]==len[p]+1)
fa[np]=q;
else{
int nq=++cnt;len[nq]=len[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[p]));
fa[nq]=fa[q];fa[q]=fa[np]=nq;
while(ch[p][c]==q)
ch[p][c]=nq,p=fa[p];
}
}
}
}sam;
char str1[MAXN],str2[MAXN];
int main()
{
int len1=0,len2=0,ans=0;
scanf("%s%s",str1,str2);
sam.Init();
while(str1[len1])
sam.Insert(str1[len1++]-'`');
int node=1,tmp=0;
for(;str2[len2];len2++){
int c=str2[len2]-'`';
if(sam.ch[node][c])
node=sam.ch[node][c],tmp++;
else{
while(node&&!sam.ch[node][c])
node=sam.fa[node];
if(node==0)
node=1,tmp=0;
else
tmp=sam.len[node]+1,node=sam.ch[node][c];
}
ans=max(ans,tmp);
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: