SPOJ LCS2 - Longest Common Substring II

LCS2 - Longest Common Substring II

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

 

求若干个字符串的最长公共子串。

 

显然,如果是所有字符串的最长公共子串,至少得是第一个字符串的一个子串,所以对第一个字符串建后缀自动机,维护所有子串。然后把每个其他的字符串扔进去跑一边,找出来最远的公共点即可。

 

 1 #include <bits/stdc++.h>
 2 
 3 const int maxn = 1e6 + 5;
 4 
 5 /* AUTOMATON */
 6 
 7 int last;
 8 int tail;
 9 int mini[maxn];
10 int maxi[maxn];
11 int step[maxn];
12 int fail[maxn];
13 int next[maxn][26];
14 
15 inline void buildAutomaton(char *s)
16 {
17     last = 1; tail = 2;
18     while (*s)
19     {
20         int c = *s++ - 'a';
21         int p = last;
22         int t = tail++;
23         step[t] = step[p] + 1;
24         mini[t] = maxi[t] = step[t];
25         while (p && !next[p][c])
26             next[p][c] = t, p = fail[p];
27         if (p)
28         {
29             int q = next[p][c];
30             if (step[q] == step[p] + 1)
31                 fail[t] = q;
32             else
33             {
34                 int k = tail++;
35                 fail[k] = fail[q];
36                 fail[q] = fail[t] = k;
37                 step[k] = step[p] + 1;
38                 mini[k] = maxi[k] = step[k];
39                 memcpy(next[k], next[q], sizeof(next[k]));
40                 while (p && next[p][c] == q)
41                     next[p][c] = k, p = fail[p];
42             }
43         }
44         else
45             fail[t] = 1;
46         last = t;
47     }
48 }
49 
50 inline void searchAutoMaton(char *s)
51 {
52     memset(maxi, 0, sizeof(maxi));
53     for (int t = 1, k = 0; *s; )
54     {
55         int c = *s++ - 'a';
56         if (next[t][c])
57             ++k, t = next[t][c];
58         else
59         {
60             while (t && !next[t][c])
61                 t = fail[t];
62             if (t)
63                 k = step[t] + 1, t = next[t][c];
64             else   
65                 k = 0, t = 1;
66         }
67         if (maxi[t] < k)
68             maxi[t] = k;
69     }
70     for (int i = tail - 1; i; --i)
71         if (maxi[fail[i]] < maxi[i])
72             maxi[fail[i]] = maxi[i];
73     for (int i = 1; i < tail; ++i)
74         if (mini[i] > maxi[i])
75             mini[i] = maxi[i];
76 }
77 
78 inline int calculate(void)
79 {
80     register int ret = 0;
81     for (int i = 1; i < tail; ++i)
82         if (ret < mini[i])
83             ret = mini[i];
84     return ret;
85 }
86 
87 /* MAIN FUNC */
88 
89 char str[maxn];
90 
91 signed main(void)
92 {
93     scanf("%s", str);
94     buildAutomaton(str);
95     while (~scanf("%s", str))
96         searchAutoMaton(str);
97     printf("%d\n", calculate());
98 }

 

@Author: YouSiki

posted @ 2016-12-22 19:53  YouSiki  阅读(199)  评论(0编辑  收藏  举报