• SPOJ 1811 Longest Common Substring SAM


    -----------------

    A string is finite sequence of characters over a non-empty finite set Σ.

    In this problem, Σ is the set of lowercase letters.

    Substring, also called factor, is a consecutive sequence of characters occurrences at least once in a string.

    Now your task is simple, for two given strings, find the length of the longest common substring of them.

    Here common substring means a substring of two or more strings.

    Input

    The input contains exactly two lines, each line consists of no more than 250000 lowercase letters, representing a string.

    Output

    The length of the longest common substring. If such string doesn't exist, print "0" instead.

    Example

    Input:
    alsdfkjfjkdsal
    fdjskalajfkdsla
    
    Output:
    3

    -----------------

    SAM用O(n)跑LCS

    -----------------

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <vector>
    #define sz(x) int(x.size())
    using namespace std;
    
    typedef vector<int> VI;
    const int maxn = 250000+10;
    
    class SuffixAutomaton{
    private:
        struct Node{
            Node *suf, *go[26];
            int val;
            Node(){
                suf=NULL;
                val=0;
                memset(go,0,sizeof(go));
            }
            void clear(){
                suf=NULL;
                val=0;
                memset(go,0,sizeof(go));
            }
            int calc(){
                if (suf==0) return 0;
                return val-suf->val;
            }
        };
        Node *root,*last;
        Node nodePool[maxn*2],*cur;
        Node* newNode(){
            Node* res=cur++;
            res->clear();
            return res;
        }
        int tot;
        void extend(int w){
            Node *p=last;
            Node *np=newNode();
            np->val=p->val+1;
            while (p&&!p->go[w]){
                p->go[w]=np;
                p=p->suf;
            }
            if (!p){
                np->suf=root;
                tot+=np->calc();
            }
            else{
                Node *q=p->go[w];
                if (p->val+1==q->val){
                    np->suf=q;
                    tot+=np->calc();
                }
                else{
                    Node *nq=newNode();
                    memcpy(nq->go,q->go,sizeof(q->go));
                    tot-=p->calc()+q->calc();
                    nq->val=p->val+1;
                    nq->suf=q->suf;
                    q->suf=nq;
                    np->suf=nq;
                    tot+=p->calc()+q->calc()+np->calc()+nq->calc();
                    while (p&&p->go[w]==q){
                        p->go[w]=nq;
                        p=p->suf;
                    }
                }
            }
            last = np;
        }
    public:
        void init(){
            cur=nodePool;
            root=newNode();
            last=root;
        }
        VI getSubString(char s[]){
            VI v;
            tot=0;
            int len=strlen(s);
            for (int i=0;i<len;i++){
                extend(s[i]-'a');
                v.push_back(tot);
            }
            return v;
        }
        int getLCS(char A[],char B[]){
            int res=0,step=0;
            int lenA=strlen(A);
            int lenB=strlen(B);
            for (int i=0;i<lenA;i++) extend(A[i]-'a');
            Node *p=root;
            for (int i=0;i<lenB;i++){
                int x=B[i]-'a';
                if (p->go[x]){
                    step++;
                    p=p->go[x];
                }
                else{
                    while (p&&!p->go[x]) p=p->suf;
                    if (!p){
                        p=root;
                        step=0;
                    }
                    else{
                        step=p->val+1;
                        p=p->go[x];
                    }
                }
                res=max(res,step);
            }
            return res;
        }
    }atm;
    char A[maxn],B[maxn];
    int main()
    {
        while (~scanf("%s%s",A,B)){
            atm.init();
            printf("%d
    ",atm.getLCS(A,B));
        }
        return 0;
    }
    

    -----------------

    -----------------

    -----------------

  • 相关阅读:
    构建之法阅读笔记05
    第十一周的学习进度条
    第十周的学习进度条
    第九周的学习进度条
    UI分析之石家庄铁道大学官网
    个人工作总结10
    个人工作总结09
    Lua 笔记16
    Lua 笔记15
    Lua 笔记14
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681553.html
Copyright © 2020-2023  润新知