码迷,mamicode.com
首页 > 其他好文 > 详细

SPOJ 1811 Longest Common Substring

时间:2018-03-06 23:15:25      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:color   tar   cstring   ast   name   pos   bst   last   size   

http://www.spoj.com/problems/LCS/

 

题意:求两个串的最长公共子串

 

用一个串建后缀自动机,另一个串在上面类似于fail树的方式跑

不匹配时到它的parent树上的父节点,相当于保留当前最长匹配后缀

 

#include<cstdio>
#include<cstring>

using namespace std;

#define N 250002

#define max(x,y) x>y ? x: y

char s1[N],s2[N];

int ch[N<<1][26],fa[N<<1],tot=1;
int len[N<<1];
int last=1,p,np,q,nq;

void extend(int c)
{
    len[np=++tot]=len[last]+1;
    for(p=last;p && !ch[p][c];p=fa[p])     ch[p][c]=np;
    if(!p)  fa[np]=1;
    else
    {
        q=ch[p][c];
        if(len[q]==len[p]+1) fa[np]=q;
        else
        {
            nq=++tot;
            memcpy(ch[nq],ch[q],sizeof(ch[nq]));
            fa[nq]=fa[q];
            fa[q]=fa[np]=nq;
            len[nq]=len[p]+1;
            for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
        }
    }
    last=np;
}

void go()
{
    int l=strlen(s2+1);
    int now=1,ans=0,now_len=0;
    int c;
    for(int i=1;i<=l;++i)
    {
        c=s2[i]-a;
        while(now && !ch[now][c])
        {
            now=fa[now];
            now_len=len[now];
        }
        if(!now) 
        {
            now_len=0;
            now=1;
        }
        else if(ch[now][c])
        {
            now_len++;
            now=ch[now][c];
            ans=max(ans,now_len);
        }
    }
    printf("%d",ans);
}

int main()
{
    scanf("%s%s",s1+1,s2+1);
    int l=strlen(s1+1);
    for(int i=1;i<=l;++i) extend(s1[i]-a);
    go();
}
    

 

SPOJ 1811 Longest Common Substring

标签:color   tar   cstring   ast   name   pos   bst   last   size   

原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8516883.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!