spoj1812 LCS2 - Longest Common Substring II

地址:http://www.spoj.com/problems/LCS2/

题面:

LCS2 - Longest Common Substring II

no tags

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

思路:

  对第一个穿构建sam,然后让后面的串在sam上走,同时记录每个串跑完后各个状态的所能匹配的最长长度,然后对所有串取个最小值,之后再取个最大值。

  注意:如果状态p能够到达,那么状态fa[p]也必然能够到达,但可能在匹配时不会走到fa[p]状态,所以当p可达时,要更新fa[p]。

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 struct SAM
 6 {
 7     static const int MAXN = 100001<<1;//大小为字符串长度两倍
 8     static const int LetterSize = 26;
 9
10     int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
11     int sum[MAXN], tp[MAXN]; //用于拓扑排序,tp为排序后的数组
12
13     void init( void)
14     {
15         last = tot = 1;
16         len[1] = 0;
17         memset(ch,0,sizeof ch);
18         memset(fa,0,sizeof fa);
19     }
20
21     void add( int x)
22     {
23         int p = last, np = last = ++tot;
24         len[np] = len[p] + 1;
25         while( p && !ch[p][x]) ch[p][x] = np, p = fa[p];
26         if( p == 0)
27             fa[np] = 1;
28         else
29         {
30             int q = ch[p][x];
31             if( len[q] == len[p] + 1)
32                 fa[np] = q;
33             else
34             {
35                 int nq = ++tot;
36                 memcpy( ch[nq], ch[q], sizeof ch[q]);
37                 len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq;
38                 while( p && ch[p][x] == q)  ch[p][x] = nq, p = fa[p];
39             }
40         }
41     }
42
43     void toposort( void)
44     {
45         for(int i = 1; i <= len[last]; i++)   sum[i] = 0;
46         for(int i = 1; i <= tot; i++)   sum[len[i]]++;
47         for(int i = 1; i <= len[last]; i++)   sum[i] += sum[i-1];
48         for(int i = 1; i <= tot; i++)   tp[sum[len[i]]--] = i;
49     }
50 } sam;
51 char ss[100004];
52 int ans,mx[100001<<1],mi[100001<<1];
53
54 int main(void)
55 {
56     //freopen("in.acm","r",stdin);
57     sam.init();
58     scanf("%s",ss);
59     for(int i=0,len=strlen(ss);i<len;i++)  sam.add(ss[i]-‘a‘);
60     for(int i=1;i<=sam.tot;i++) mi[i]=1e6;
61     sam.toposort();
62     while(~scanf("%s",ss))
63     {
64         for(int i=0,len=strlen(ss),p=1,cnt=0;i<len;i++)
65         {
66             int c=ss[i]-‘a‘;
67             if(sam.ch[p][c])
68                 p=sam.ch[p][c],cnt++;
69             else
70             {
71                 while(p&&!sam.ch[p][c]) p=sam.fa[p];
72                 if(!p)
73                     p=1,cnt=0;
74                 else
75                     cnt=sam.len[p]+1,p=sam.ch[p][c];
76             }
77             mx[p]=max(mx[p],cnt);
78         }
79         for(int i=sam.tot;i;i--)
80         {
81             int p=sam.tp[i];
82             mi[p]=min(mx[p],mi[p]);
83             if(mx[p]&&sam.fa[p]) mx[sam.fa[p]]=sam.len[sam.fa[p]];
84             mx[p]=0;
85         }
86     }
87     for(int i=1;i<=sam.tot;i++) ans=max(ans,mi[i]);
88     printf("%d\n",ans);
89     return 0;
90 }
时间: 2024-10-24 00:17:45

spoj1812 LCS2 - Longest Common Substring II的相关文章

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

spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 <= n <= 10 |A[i]| <= 1e5 思路: 和spoj 1811 LCS差不多的做法 把其中一个A建后缀自动机 考虑一个状态s, 如果A之外的其他串对它的匹配长度分别是a[1], a[2], ..., a[n - 1], 那么min(a[1], a[2], ..., a[n - 1]

spoj 1812 LCS2 - Longest Common Substring II (后缀自己主动机)

spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 <= n <= 10 |A[i]| <= 1e5 思路: 和spoj 1811 LCS几乎相同的做法 把当中一个A建后缀自己主动机 考虑一个状态s, 假设A之外的其它串对它的匹配长度各自是a[1], a[2], ..., a[n - 1], 那么min(a[1], a[2], ..., a[n -

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 t

SPOJ LCS2 - Longest Common Substring II 字符串 SAM

原文链接http://www.cnblogs.com/zhouzhendong/p/8982484.html 题目传送门 - SPOJ LCS2 题意 求若干$(若干<10)$个字符串的最长公共连续子串长度. 串长$\leq 100000$ 题解 建议在做本题之前,先去做SPOJ LCS,本题是其升级版. 题解链接 - SPOJ LCS - http://www.cnblogs.com/zhouzhendong/p/8982392.html 对于本题,我们只需要保持一下之后每一个串在第一个串的$

SP1812 LCS2 - Longest Common Substring II

\(\color{#0066ff}{ 题目描述 }\) 题面描述 给定一些字符串,求出它们的最长公共子串 输入格式 输入至多\(10\) 行,每行包含不超过\(100000\) 个的小写字母,表示一个字符串 输出格式 一个数,最长公共子串的长度 若不存在最长公共子串,请输出\(0\) . \(\color{#0066ff}{输入格式}\) 几个字符串 \(\color{#0066ff}{输出格式}\) 一个整数,为 所求答案 \(\color{#0066ff}{输入样例}\) alsdfkjfj

SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机)【两种做法】

手动博客搬家: 本文发表于20181217 23:54:35, 原地址https://blog.csdn.net/suncongbo/article/details/85058680 人生第一道后缀自动机. 说实话SAM我还没学多么明白. 但是题还是要做的. 说起来这玩意真的很妙.可惜我智商低理解不了. 再次验证了代码能力菜到没边.hyw 30min写完我写2.5h. 题目链接 (洛谷) https://www.luogu.org/problemnew/show/SP1812 题目大意 给\(n

SPOJ - LCS2 Longest Common Substring II(后缀自动机)题解

题意: 求\(n\)个串的最大\(LCS\). 思路: 把第一个串建后缀自动机,然后枚举所有串.对于每个串,求出这个串在\(i\)节点的最大匹配为\(temp[i]\)(当前串在这个节点最多取多少),然后我们求出最终所有串在\(i\)节点的匹配最小值\(mn[i]\)(即为所有串在\(i\)节点都能取到多少),答案即为\(max\{min[i]\}\). 但是我们能发现,如果我们更新了\(temp[i]\),那么其实\(fa[i]\)的\(temp[fa[i]]\)也应该要更新,因为父节点是我的

SPOJ LCS2 1812. Longest Common Substring II

SPOJ Problem Set (classical) 1812. Longest Common Substring II Problem code: 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 consecu

SPOJ Longest Common Substring II

Longest Common Substring II Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on SPOJ. Original ID: LCS264-bit integer IO format: %lld      Java class name: Main A string is finite sequence of characters over a non-empty finite se