Longest Common Substring
Description
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
好不容易找到了一个真正的模板题,却被虐得满身疮痍……
//愤怒.jpg
/|
/\ / \ /\
/ \/ \/ \
/┏┻┻┻┻┻┻┻┓\
|┃# ┏┓ ┏┓ ┃ /
\┃ ┗┛ A┗┛ ┃ /
\┗━━━━━━━┛ \
\ | | /
咱以TLE了十余次的惨痛教训告诫大家:strlen不能放在for循环的终止条件中!!!
思路:
这还有什么思路(笑)裸的后缀自动机~
好吧其实是对第一个串建好后缀自动机,拿第二个串在自动机上面匹配即可~
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int N=500011;
struct SAM
{
int next[N][26],fa[N],len[N];
int pool,u;
inline void init()
{
pool=u=1;
memset(next,0,sizeof(next));
memset(len,0,sizeof(len));
memset(fa,0,sizeof(fa));
}
int insert(int v)
{
int now=++pool;
len[now]=len[u]+1;
while(!next[u][v] && u)
next[u][v]=now,u=fa[u];
if(!u)
fa[now]=1;
else
{
int q=next[u][v];
if(len[q]==len[u]+1)
fa[now]=q;
else
{
int newq=++pool;
memcpy(next[newq],next[q],sizeof(next[q]));
len[newq]=len[u]+1;
fa[newq]=fa[q];
fa[now]=fa[q]=newq;
while(next[u][v]==q)
next[u][v]=newq,u=fa[u];
}
}
u=now;
return u;
}
int run(char *s)
{
int now=1;
int ans=0,tmp=0;
for(int i=0;i<strlen(s);i++)
{
if(next[now][s[i]-'a'])
tmp++,now=next[now][s[i]-'a'];
else
{
while(now && !next[now][s[i]-'a'])
now=fa[now];
if(!now)
now=1,tmp=0;
else
tmp=len[now]+1,now=next[now][s[i]-'a'];
}
if(tmp>ans)
ans=tmp;
}
return ans;
}
}koishi;
int main()
{
koishi.init();
char s[N],t[N];
scanf("%s",&s);
int len=strlen(s);
for(int i=0;i<len;i++)
koishi.insert(s[i]-'a');
scanf("%s",&t);
printf("%d\n",koishi.run(t));
return 0;
}
本文介绍了一种利用后缀自动机解决两个字符串之间最长公共子串问题的方法。通过构建后缀自动机并进行匹配,有效地找出最长公共子串的长度。
1466

被折叠的 条评论
为什么被折叠?



