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
Notice:
new testcases added
思路
代码
#include <cstdio>
#include <cstring>
const int maxn=250000;
struct node
{
node* tr[26];
node* par;
int maxl;
node(int l=0)
{
memset(tr,0,sizeof tr);
par=NULL;
maxl=l;
}
};
struct suffix_automaton
{
node* qs;
node* qlast;
node* qn[maxn+10];
int l[maxn+10];
inline int clear()
{
delete qs;
delete qlast;
qlast=qs=new node();
return 0;
}
inline int addchr(int ch)
{
node* p=qlast;
node* np=new node(qlast->maxl+1);
qlast=np;
while((p!=NULL)&&(p->tr[ch]==NULL))
{
p->tr[ch]=np;
p=p->par;
}
if(p==NULL)
{
np->par=qs;
return 0;
}
node* q=p->tr[ch];
if(q->maxl!=p->maxl+1)
{
node* nq=new node(p->maxl+1);
memcpy(nq->tr,q->tr,sizeof q->tr);
nq->par=q->par;
q->par=np->par=nq;
while((p!=NULL)&&(p->tr[ch]==q))
{
p->tr[ch]=nq;
p=p->par;
}
}
else
{
np->par=q;
}
return 0;
}
inline int run(char* s,int len)
{
qn[0]=qs;
l[0]=0;
for(register int i=1; i<=len; ++i)
{
node* nq=qn[i-1];
if(nq->tr[s[i]-'a']!=NULL)
{
l[i]=l[i-1]+1;
qn[i]=nq->tr[s[i]-'a'];
continue;
}
while((nq!=NULL)&&(nq->tr[s[i]-'a']==NULL))
{
nq=nq->par;
}
if(nq==NULL)
{
qn[i]=qs;
l[i]=0;
continue;
}
qn[i]=nq->tr[s[i]-'a'];
l[i]=nq->maxl+1;
}
int ans=0;
for(register int i=1; i<=len; ++i)
{
if(l[i]>ans)
{
ans=l[i];
}
}
return ans;
}
};
suffix_automaton sam;
int la,lb,l[maxn+10];
char a[maxn+10],b[maxn+10];
int main()
{
scanf("%s%s",a+1,b+1);
la=strlen(a+1);
lb=strlen(b+1);
sam.clear();
for(register int i=1; i<=lb; ++i)
{
sam.addchr(b[i]-'a');
}
printf("%d\n",sam.run(a,la));
return 0;
}