spoj1811 Longest Common Substring

来源:互联网 发布:随机森林算法优化研究 编辑:程序博客网 时间:2024/06/05 08:48

1811. Longest Common Substring

Problem 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:alsdfkjfjkdsalfdjskalajfkdslaOutput: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 600010char 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;}


0 0
原创粉丝点击