后缀自动机(SAM) :SPOJ LCS

LCS - Longest Common Substring

no tags 

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。
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 const int MAXN=1000010;
 6 struct SAM{
 7     int fa[MAXN],ch[MAXN][27],len[MAXN],cnt,last;
 8     void Init()
 9     {
10         last=cnt=1;
11     }
12     void Insert(int c)
13     {
14         int p=last,np=last=++cnt;
15         len[np]=len[p]+1;
16         while(!ch[p][c]&&p)
17             ch[p][c]=np,p=fa[p];
18         if(!p)fa[np]=1;
19         else{
20             int q=ch[p][c];
21             if(len[q]==len[p]+1)
22                 fa[np]=q;
23             else{
24                 int nq=++cnt;len[nq]=len[p]+1;
25                 memcpy(ch[nq],ch[q],sizeof(ch[p]));
26                 fa[nq]=fa[q];fa[q]=fa[np]=nq;
27                 while(ch[p][c]==q)
28                     ch[p][c]=nq,p=fa[p];
29             }    
30         }    
31     }
32 }sam; 
33 char str1[MAXN],str2[MAXN];
34 int main()
35 {
36     int len1=0,len2=0,ans=0;
37     scanf("%s%s",str1,str2);
38     sam.Init();
39     while(str1[len1])
40         sam.Insert(str1[len1++]-'`');
41     int node=1,tmp=0;
42     for(;str2[len2];len2++){
43         int c=str2[len2]-'`';
44         if(sam.ch[node][c])
45             node=sam.ch[node][c],tmp++;
46         else{
47             while(node&&!sam.ch[node][c])
48                 node=sam.fa[node];
49             if(node==0)
50                 node=1,tmp=0;
51             else
52                 tmp=sam.len[node]+1,node=sam.ch[node][c];        
53         }
54         ans=max(ans,tmp);
55     }
56     printf("%d
",ans);
57     return 0;
58 }
尽最大的努力,做最好的自己!
原文地址:https://www.cnblogs.com/TenderRun/p/5215427.html