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 ", calculate()); 98 }
@Author: YouSiki