spoj1811 LCS - Longest Common Substring

地址:http://www.spoj.com/problems/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

思路:
  对于串a建立后缀自动机, 然后让串b在sam上能走,记录到达每个状态时的长度,取个max就行。
 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 struct SAM
 6 {
 7     static const int MAXN = 3e5 * 2;//大小为字符串长度两倍
 8     static const int LetterSize = 26;
 9     int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
10 
11     void init( void)
12     {
13         last = tot = 1;
14         len[1] = 0;
15         memset(ch,0,sizeof ch);
16         memset(fa,0,sizeof fa);
17     }
18 
19     void add( int x)
20     {
21         int p = last, np = last = ++tot;
22         len[np] = len[p] + 1;
23         while( p && !ch[p][x]) ch[p][x] = np, p = fa[p];
24         if( p == 0)
25             fa[np] = 1;
26         else
27         {
28             int q = ch[p][x];
29             if( len[q] == len[p] + 1)
30                 fa[np] = q;
31             else
32             {
33                 int nq = ++tot;
34                 memcpy( ch[nq], ch[q], sizeof ch[q]);
35                 len[nq] = len[p] + 1;
36                 fa[nq] = fa[q], fa[q] = fa[np] = nq;
37                 while( p && ch[p][x] == q)
38                     ch[p][x] = nq, p = fa[p];
39             }
40         }
41     }
42 };
43 char sa[300000],sb[300000];
44 SAM sam;
45 int main(void)
46 {
47     scanf("%s%s",sa,sb);
48     int len=strlen(sa),ans=0;
49     sam.init();
50     for(int i=0;i<len;i++)
51         sam.add(sa[i]-'a');
52     len=strlen(sb);
53     for(int i=0,p=1,cnt=0;i<len;i++)
54     {
55         int k=sb[i]-'a';
56         if(sam.ch[p][k])
57             p=sam.ch[p][k],cnt++;
58         else
59         {
60             while(p&&!sam.ch[p][k])  p=sam.fa[p];
61             if(p==0)
62                 p=1,cnt=0;
63             else
64                 cnt=sam.len[p]+1,p=sam.ch[p][k];
65         }
66         ans=max(ans,cnt);
67     }
68     printf("%d\n",ans);
69     return 0;
70 }

 

posted @ 2017-09-13 21:17  weeping  阅读(149)  评论(0编辑  收藏  举报