SPOJ 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

Notice: new testcases added

 

就是求多个字符串的最长公共子串

后缀自动机

用第一个串建后缀自动机,然后在这个自动机上花式转移。

solve()里面tmp没初始化,调了半天……

 

 1 /*by SilverN*/
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 using namespace std;
 8 const int mxn=200010;
 9 int read(){
10     int x=0,f=1;char ch=getchar();
11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
13     return x*f;
14 }
15 struct SAM{
16     int t[mxn][27],l[mxn];
17     int fa[mxn];
18     int S,last,cnt;
19     int rk[mxn],w[mxn],mx[mxn],mn[mxn];
20     void init(){S=last=cnt=1;return;}
21     void add(int c){
22         int p=last,np=++cnt;last=np;
23         l[np]=l[p]+1;
24         for(;p && !t[p][c];p=fa[p])t[p][c]=np;
25         if(!p)
26             fa[np]=S;
27         else{
28             int q=t[p][c];
29             if(l[p]+1==l[q])
30                 fa[np]=q;
31             else{
32                 int nq=++cnt;
33                 l[nq]=l[p]+1;
34                 memcpy(t[nq],t[q],sizeof t[q]);
35                 fa[nq]=fa[q];
36                 fa[q]=fa[np]=nq;
37                 for(;t[p][c]==q;p=fa[p])t[p][c]=nq;
38             }
39         }
40     }
41     void st(int len){
42         for(int i=1;i<=cnt;i++){
43             mn[i]=l[i];    w[l[i]]++;
44         }
45         for(int i=1;i<=len;i++)w[i]+=w[i-1];
46         for(int i=1;i<=cnt;i++)rk[w[l[i]]--]=i;
47         return;
48     }
49     void solve(char *s){
50         int now=S,len=strlen(s+1),tmp=0;
51         memset(mx,0,sizeof mx);
52         int i,j;
53         for(i=1;i<=len;i++){
54             int c=s[i]-'a';
55             if(t[now][c]){tmp++;now=t[now][c];}
56             else{
57                 while(now && !t[now][c])now=fa[now];
58                 if(!now){tmp=0;now=S;}
59                 else{tmp=l[now]+1;now=t[now][c];}
60             }
61             mx[now]=max(mx[now],tmp);
62         }
63         for(i=cnt;i;i--){
64             now=rk[i];
65             if(mx[now]<mn[now])mn[now]=mx[now];//多串对应位置取最小值
66             if(fa[now] && mx[now])mx[fa[now]]=max(mx[fa[now]],mx[now]);
67         }
68     }
69 }sa;
70 char s[mxn];
71 int main(){
72     int i,j;
73     scanf("%s",s+1);
74     int len=strlen(s+1);
75     sa.init();
76     for(i=1;i<=len;i++)sa.add(s[i]-'a');
77     sa.st(len);
78     while(scanf("%s",s+1)!=EOF){
79         sa.solve(s);
80     }
81     int ans=0;
82     for(i=1;i<=sa.cnt;i++){
83         ans=max(ans,sa.mn[i]);
84     }
85     printf("%d\n",ans);
86     return 0;
87 }

 

(没放代码就保存了页面,过了好久才发现,也是蠢)

 

posted @ 2017-02-16 18:10  SilverNebula  阅读(324)  评论(0编辑  收藏  举报
AmazingCounters.com