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;
}