Suffix automaton seeking more strings LCS - spojlcs2

/ * 
Each state storage longest match length, and a plurality of string matching process takes a minimum length of the longest match 
different places and LCS1: LCS long lived maintenance current longest match length match length and can, but multiple string matching the need to maintain state information for each node (i.e., the suffix tree) is 
therefore able to save two values Max, Min for each state, each state represents the longest match for the string length, and all had been matched the minimum length of the longest match string in this state 
after a string of matching suffix tree back from a bottom up, update Max value 
update after the update is completed Max Min 
* / 
#include <bits / STDC ++. H >
 the using  namespace STD;
 #define MAXN 400005
 struct the SAM {
     int Last, CNT;
     int NXT [MAXN] [ 26 is ], len [MAXN], Link [MAXN]; 
    the SAM () {Last = CNT = . 1 ;}
     void the Add ( int C) {
         int P = Last, NP = Last ++ =cnt;
        len[np]=len[p]+1;

        for(;p&&!nxt[p][c];p=link[p])
            nxt[p][c]=np;
        if(!p){link[np]=1;return;}
        
        int q=nxt[p][c];
        if(len[q]==len[p]+1){link[np]=q;return;}
        
        int clone=++cnt;
        link[clone]=link[q];
        len[clone]=len[p]+1;
        memcpy(nxt[clone],nxt[q],sizeof nxt[q]);
        link[q]=link[np]=clone;
        for(;p&&nxt[p][c]==q;p=link[p])
            nxt[p][c]=clone;
    }
    int Min[maxn],Max[maxn],t[maxn],id[maxn];
    void sort(){
        for(int i=1;i<=cnt;i++)t[len[i]]++;
        for(int i=1;i<=cnt;i++)t[i]+=t[i-1];
        for(int i=1;i<=cnt;i++)id[t[len[i]]--]=i;
        for(int i=1;i<=cnt;i++)Min[i]=len[i];
    }
    void update(char *s){
        memset(Max,0,sizeof Max);
        int now=1,cur=0,Len=strlen(s);
        for(int i=0;i<Len;i++){
            int p=s[i]-'a';
            if(nxt[now][p]){
                cur++;
                now=nxt[now][p];
            }else {
                while(now && !nxt[now][p])
                    now=link[now];
                if(now){
                    cur=len[now]+1;
                    now=nxt[now][p];
                }else {
                    cur=0;now=1;
                }
            }
            Max[now]=max(Max[now],cur);
        }
        for(int i=cnt;i>=1;i--){
            int tmp=id[i];
            Max[link[tmp]]=max(Max[link[tmp]],Max[tmp]);
        }
        for(int i=cnt;i>=1;i--)
            Min[i]=min(Min[i],Max[i]);
    }
    int calc(){
        int res=0;
        for(int i=1;i<=cnt;i++)res=max(res,Min[i]);
        return res;
    }
}p;
char s[maxn];
int main(){
    cin>>s;
    int len=strlen(s);
    for(int i=0;i<len;i++)p.add(s[i]-'a');
    p.sort();
    while(scanf("%s",s)!=EOF)
        p.update(s);
    cout<<p.calc()<<endl;
}

 

Guess you like

Origin www.cnblogs.com/zsben991126/p/11318745.html