• SPOJ 1811 Longest Common Substring


    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();
    }
        
  • 相关阅读:
    最近重感冒完全不知道知己在记什么

    倾尽一生
    学习笔记,函数
    唯美句
    02 mysql 基础二 (进阶)
    01 mysql 基础一 (进阶)
    16 正则表达式
    15 迭代器、生成器、模块和包
    14 异常
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8516883.html
Copyright © 2020-2023  润新知