SPOJ 1812 Longest Common Substring II(后缀自动机)(LCS2)

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.

 

题目大意:求多个字符串的最长公共子串。

思路:据说把多个串拼起来会MLE还是TLE?SPOJ太慢了……

给第一个串建立后缀自动机,然后把每个点的ans置为当前后缀的LCS,dp为当前某个串能匹配的最长后缀

然后每次弄完用每个点的dp更新ans……图是一个DAG……

哎呀好难说看代码吧……

 

代码(1500MS):

  1 #include <cstdio>

  2 #include <algorithm>

  3 #include <cstring>

  4 using namespace std;

  5 

  6 const int MAXN = 100000 + 10;

  7 char buf[MAXN];

  8 struct State {

  9     State *fail, *go[26];

 10     int val, dp, ans;/*

 11     State() :

 12             fail(0), val(0) {

 13         memset(go, 0, sizeof go);

 14     }*/

 15 }*root, *last;

 16 State statePool[MAXN * 2], *cur;

 17 

 18 void init() {

 19     //memset(statePool, 0, 2 * strlen(buf) * sizeof(State));

 20     cur = statePool;

 21     root = last = cur++;

 22 }

 23 

 24 void extend(int w) {

 25     State *p = last, *np = cur++;

 26     np->ans = np->val = p->val + 1;

 27     while (p && !p->go[w])

 28         p->go[w] = np, p = p->fail;

 29     if (!p) np->fail = root;

 30     else {

 31         State*q = p->go[w];

 32         if (p->val + 1 == q->val) np->fail = q;

 33         else {

 34             State *nq = cur++;

 35             memcpy(nq->go, q->go, sizeof q->go);

 36             nq->ans = nq->val = p->val + 1;

 37             nq->fail = q->fail;

 38             q->fail = nq;

 39             np->fail = nq;

 40             while (p && p->go[w] == q)

 41                 p->go[w] = nq, p = p->fail;

 42         }

 43     }

 44     last = np;

 45 }

 46 

 47 inline void update_max(int &a, const int &b) {

 48     if(a < b) a = b;

 49 }

 50 

 51 inline void update_min(int &a, const int &b) {

 52     if(a > b) a = b;

 53 }

 54 

 55 struct Node {

 56     State *p;

 57     bool operator < (const Node &rhs) const {

 58         return p->val < rhs.p->val;

 59     }

 60 } a[MAXN * 2];

 61 

 62 int main() {

 63     init();

 64     scanf("%s", buf);

 65     for(char *pt = buf; *pt; ++pt)

 66         extend(*pt - 'a');

 67     int m = 0;

 68     for(State *p = statePool; p != cur; ++p) {

 69         a[m++].p = p;

 70     }

 71     sort(a, a + m);

 72     int n = 0;

 73     while(scanf("%s", buf) != EOF) {

 74         ++n;

 75         State *t = root;

 76         int l = 0;

 77         for(char *pt = buf; *pt; ++pt) {

 78             int w = *pt - 'a';

 79             if(t->go[w]) {

 80                 t = t->go[w];

 81                 update_max(t->dp, ++l);

 82             }

 83             else {

 84                 while(t && !t->go[w]) t = t->fail;

 85                 if(!t) l = 0, t = root;

 86                 else {

 87                     l = t->val;

 88                     t = t->go[w];

 89                     update_max(t->dp, ++l);

 90                 }

 91             }

 92         }

 93         for(int i = m - 1; i > 0; --i) {

 94             State *p = a[i].p;

 95             update_min(p->ans, p->dp);

 96             update_max(p->fail->dp, min(p->dp, max(p->fail->val, p->dp)));

 97             p->dp = 0;

 98         }

 99     }

100     int ans = 0;

101     for(int i = m - 1; i >= 0; --i) update_max(ans, a[i].p->ans);

102     printf("%d\n", ans);

103 }
View Code

 

你可能感兴趣的:(substring)