spoj Longest Common Substring

Longest Common Substring

 SPOJ - LCS 

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

/*
    对一个串建立后缀自动机,用另一个串上去匹配
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 250002
using namespace std;
char s1[maxn],s2[maxn];
int ch[maxn<<1][26],fa[maxn<<1],tot=1,len[maxn<<1],last=1,p,np,q,nq;
void Insert(int c){
    np=++tot;
    len[np]=len[last]+1;
    p=last;
    while(p&&!ch[p][c])ch[p][c]=np,p=fa[p];
    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;
            while(ch[p][c]==q)ch[p][c]=nq,p=fa[p];
        }
    }
    last=np;
}
void solve(){
    int l=strlen(s2+1),now=1,ans=0,now_len=0,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++)Insert(s1[i]-'a');
    solve();
    return 0;
}

 

posted @ 2018-04-10 10:45  Echo宝贝儿  阅读(121)  评论(0编辑  收藏  举报