SPOJ

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 a bit harder, for some 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 at most 10 lines, each line consists of no more than 100000 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
aaaajfaaaa

Output:
2

Notice: new testcases added

后缀自动机的入门题目

代码如下:


#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>

using namespace std;
const int N=100010;
typedef long long ll;
struct State
{
    State *link,*go[26];
    int step;
    int nl;
    int ml;
    void clear()
    {
        nl=0;
        ml=0;
        link=0;
        step=0;
        memset(go,0,sizeof(go));
    }
}*root,*last;

State statePool[N*2],*b[N*2],*cur;

void init()
{
    cur=statePool;
    root=last=cur++;
    root->clear();
}

void Insert(int w)
{
    State *p=last;
    State *np=cur++;
    np->clear();
    np->step=p->step+1;
    np->ml=p->step+1;
    while(p&&!p->go[w])
        p->go[w]=np,p=p->link;
    if(p==0)
        np->link=root;
    else
    {
        State *q=p->go[w];
        if(p->step+1==q->step)
            np->link=q;
        else
        {
            State *nq=cur++;
            nq->clear();
            memcpy(nq->go,q->go,sizeof(q->go));
            nq->step=p->step+1;
            nq->ml=nq->step;
            nq->link=q->link;
            q->link=nq;
            np->link=nq;
            while(p&&p->go[w]==q)
                p->go[w]=nq, p=p->link;
        }
    }
    last=np;
}

char A[N],B[N];
int cnt[N];
int main()
{
    int maxx,len,len1,lenb;
        scanf("%s",A);
         len=strlen(A);
         init();
         for(int i=0;i<len;i++)
          Insert(A[i]-'a');
          State *p;
          memset(cnt,0,sizeof(cnt));
    for(p=statePool;p!=cur;p++)
      cnt[p->step]++;
    for(int i=1;i<=len;i++)
      cnt[i]+=cnt[i-1];
    for(p=statePool;p!=cur;p++)
      b[--cnt[p->step]]=p;
     while(scanf("%s",B)!=EOF)
     {
         lenb=strlen(B);
         for(p=statePool;p!=cur;p++)
          p->nl=0;
         p=root;
         len1=0;
         for(int i=0;i<lenb;i++)
         {
             int x=B[i]-'a';
             if(p->go[x])
             {
                len1++;
                p=p->go[x];
             }
             else
             {
               while(p&&!p->go[x])p=p->link;
               if(p==NULL)
               {
                 p=root;
                 len1=0;
               }
               else
               {
                 len1=p->step+1;
                 p=p->go[x];
               }
             }
           p->nl=max(p->nl,len1);
         }
        int  L=cur-statePool;
        for(int i=L-1;i>0;i--)
        {
            p=b[i];
           p->ml=min(p->nl,p->ml);
           if(p->ml>0)
          p->link->nl=p->link->step;
        }

     }
   int ans=0;
     for(p=statePool;p!=cur;p++)
     ans=max(p->ml,ans);
    printf("%d
",ans);
    return 0;
}
 


原文地址:https://www.cnblogs.com/a249189046/p/7704182.html