标签:
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.
The input contains at most 10 lines, each line consists of no more than 100000 lowercase letters, representing a string.
The length of the longest common substring. If such string doesn‘t exist, print "0" instead.
Input: alsdfkjfjkdsal fdjskalajfkdsla aaaajfaaaa Output: 2
解题:后缀自动机。。。。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 100010; 4 struct node { 5 int son[26],f,len; 6 void init() { 7 f = -1; 8 len = 0; 9 memset(son,-1,sizeof son); 10 } 11 }; 12 struct SAM { 13 node e[maxn<<1]; 14 int tot,last; 15 void init() { 16 tot = last = 0; 17 e[tot++].init(); 18 } 19 int newnode(int len = 0) { 20 e[tot].init(); 21 e[tot].len = len; 22 return tot++; 23 } 24 void extend(int c) { 25 int p = last,np = newnode(e[p].len + 1); 26 while(p != -1 && e[p].son[c] == -1) { 27 e[p].son[c] = np; 28 p = e[p].f; 29 } 30 if(p == -1) e[np].f = 0; 31 else { 32 int q = e[p].son[c]; 33 if(e[p].len + 1 == e[q].len) e[np].f = q; 34 else { 35 int nq = newnode(); 36 e[nq] = e[q]; 37 e[nq].len = e[p].len + 1; 38 e[q].f = e[np].f = nq; 39 while(p != -1 && e[p].son[c] == q) { 40 e[p].son[c] = nq; 41 p = e[p].f; 42 } 43 } 44 } 45 last = np; 46 } 47 } sam; 48 int c[maxn],sa[maxn<<1],dp[maxn<<1]; 49 char str[maxn]; 50 int main() { 51 sam.init(); 52 scanf("%s", str); 53 int slen = strlen(str); 54 for (int i = 0; i < slen; ++i) sam.extend(str[i] - ‘a‘); 55 for (int i = 1; i < sam.tot; ++i) c[sam.e[i].len]++; 56 for (int i = 1; i <= slen; ++i) c[i] += c[i-1]; 57 for (int i = sam.tot-1; i > 0; --i) sa[c[sam.e[i].len]--] = i; 58 node *ele = sam.e; 59 while (scanf("%s", str) != EOF) { 60 slen = strlen(str); 61 int len = 0; 62 for (int i = 0, p = 0; i < slen; ++i) { 63 int c = str[i] - ‘a‘; 64 if (ele[p].son[c] != -1) { 65 ++len; 66 p = ele[p].son[c]; 67 dp[p] = max(len, dp[p]); 68 } else { 69 while (p != -1 && ele[p].son[c] == -1) p = ele[p].f; 70 if (p != -1) { 71 len = ele[p].len + 1; 72 p = ele[p].son[c]; 73 dp[p] = max(len, dp[p]); 74 } else len = p = 0; 75 } 76 } 77 for (int i = sam.tot-1; i > 0; --i) { 78 int v = sa[i]; 79 ele[v].len = min(ele[v].len, dp[v]); 80 dp[ele[v].f] = max(dp[ele[v].f], dp[v]); 81 dp[v] = 0; 82 } 83 } 84 int ans = 0; 85 for (int i = 1; i < sam.tot; ++i) 86 ans = max(ans, ele[i].len); 87 printf("%d\n", ans); 88 return 0; 89 }
SPOJ Longest Common Substring II
标签:
原文地址:http://www.cnblogs.com/crackpotisback/p/4774864.html