zoukankan      html  css  js  c++  java
  • spoj Longest Common Substring II

    Longest Common Substring II

     SPOJ - LCS2 

    求10个串的LCS

    /*
        1、用第一个串建立后缀自动机
        2、len[s] 表示状态s 所能代表的字符串的最大长度
          mx[s] 表示状态s 在 当前匹配的串的最长匹配后缀长度
          ans[s] 表示状态s 在所有串的最长匹配后缀长度
        3、用第2——第10个串在后缀自动机上跑,每次mx[s]=max(mx[s],当前匹配长度)
          每一个串跑完之后,更新 ans[s]=min(ans[s],mx[s])
        4、每次匹配完一个字符串的时候,要 从后缀自动机 parent 树 上的叶子节点 向根更新,
          因为后缀自动机的parent树上,min[s]=max(fa[s])+1,所以子节点能匹配的长度 比 父节点的max要长。父节点是子节点的后缀,父节点可以匹配子节点的后max(fa[s])位,但是在那串在后缀自动机上跑的时候,不能保证经过 s 的 时候 也经过了s到根的链。所以只要子节点s 有匹配长度,父节点的mx[fa[s]]即可修改为len[fa[s]]即max(fa[s])
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 100010
    using namespace std;
    char s[maxn];
    int len[maxn<<1],ch[maxn<<1][26],fa[maxn<<1],sz=1,last=1,p,q,np,nq;
    int c[maxn],sa[maxn<<1],mx[maxn<<1],ans[maxn<<1];
    void Insert(int c){
        np=++sz;
        len[np]=len[last]+1;
        ans[sz]=len[sz];
        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=++sz;
                memcpy(ch[nq],ch[q],sizeof(ch[q]));
                fa[nq]=fa[q];
                fa[q]=fa[np]=nq;
                ans[nq]=len[nq]=len[p]+1;
                while(ch[p][c]==q)ch[p][c]=nq,p=fa[p];
            }
        }
        last=np;
    }
    void solve(){
        int l,c,now,nowlen,x;
        while(scanf("%s",s+1)!=EOF){
            l=strlen(s+1);
            now=1;nowlen=0;
            for(int i=1;i<=l;i++){
                c=s[i]-'a';
                while(now&&!ch[now][c]){
                    now=fa[now];
                    nowlen=len[now];
                }
                if(!now){
                    nowlen=0;
                    now=1;
                }
                else if(ch[now][c]){
                    nowlen++;
                    now=ch[now][c];
                }
                mx[now]=max(mx[now],nowlen);
            }
            for(int i=sz;i;i--){
                x=sa[i];
                ans[x]=min(ans[x],mx[x]);
                if(fa[x]&&mx[x])mx[fa[x]]=len[fa[x]];
                mx[x]=0;
            }
        }
        int Ans=0;
        for(int i=1;i<=sz;i++)Ans=max(Ans,ans[i]);
        printf("%d",Ans);
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        scanf("%s",s+1);
        int l=strlen(s+1);
        for(int i=1;i<=l;i++)Insert(s[i]-'a');
        for(int i=1;i<=sz;i++)c[len[i]]++;
        for(int i=1;i<=l;i++)c[i]+=c[i-1];
        for(int i=sz;i;i--)sa[c[len[i]]--]=i;
        solve();
        return 0;
    }
  • 相关阅读:
    CORS实践
    xunsearch使用记录
    apk的php解析
    MYSQLI_USE_RESULT or MYSQLI_STORE_RESULT
    企业图谱
    《软件需求工程》阅读笔记03
    2020年下半年学习进度12
    《软件需求工程》阅读笔记02
    2020年下半年学习进度11
    《软件需求工程》阅读笔记01
  • 原文地址:https://www.cnblogs.com/thmyl/p/8779164.html
Copyright © 2011-2022 走看看