SPOJ Longest Common Substring II

Longest Common Substring II

Time Limit: 2000ms
Memory Limit: 262144KB
This problem will be judged on SPOJ. Original ID: LCS2
64-bit integer IO format: %lld      Java class name: Main
 

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 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 }
View Code

 

posted @ 2015-09-01 09:28  狂徒归来  阅读(178)  评论(0编辑  收藏  举报