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

发现了我原来对sam的理解的一个坑233

本题容易看出就是将所有匹配长度记录在状态上然后取min后再对所有状态取max。

但是不要忘记了一点:更新parent树的祖先。

为什么呢?首先如果子树被匹配过了,那么长度一定大于任意祖先匹配的长度(甚至有些祖先匹配长度为0!为什么呢,因为我们在匹配的过程中,只是找到一个子串,可能还遗漏了祖先没有匹配到,这样导致了祖先的记录值为0,那么在对对应状态取min的时候会取到0,这样就wa了。而且注意,如果匹配到了当前节点,那么祖先们一定都可以赋值为祖先的length!因为当前节点的length大于任意祖先。(

比如数据

acbbc
bc
ac

答案应该是1没错吧。如果没有更新祖先,那么答案会成0。

这个多想想就行了。

所以以后记住:对任意多串匹配时,凡是对同一个状态取值时,要注意当前状态的子树是否比当前状态记录的值优。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } struct sam {
static const int N=250005;
int c[N][26], l[N], f[N], root, last, cnt, mx[N], x[N];
sam() { cnt=0; root=last=++cnt; }
void add(int x) {
int now=last, a=++cnt; last=a;
l[a]=l[now]+1;
for(; now && !c[now][x]; now=f[now]) c[now][x]=a;
if(!now) f[a]=root;
else {
int q=c[now][x];
if(l[q]==l[now]+1) f[a]=q;
else {
int b=++cnt;
memcpy(c[b], c[q], sizeof c[q]);
l[b]=l[now]+1;
f[b]=f[q];
f[q]=f[a]=b;
for(; now && c[now][x]==q; now=f[now]) c[now][x]=b;
}
}
}
void build(char *s) {
int len=strlen(s);
rep(i, len) add(s[i]-'a');
for1(i, 1, cnt) mx[l[i]]++;
for1(i, 1, len) mx[i]+=mx[i-1];
for1(i, 1, cnt) x[mx[l[i]]--]=i;
for1(i, 1, cnt) mx[i]=l[i];
}
void find(char *s) {
int now=root, t=0, len=strlen(s);
static int arr[N];
rep(i, len) {
int k=s[i]-'a';
if(c[now][k]) ++t, now=c[now][k];
else {
while(now && !c[now][k]) now=f[now];
if(!now) t=0, now=root;
else t=l[now]+1, now=c[now][k];
}
arr[now]=max(arr[now], t);
}
for3(i, cnt, 1) {
t=x[i];
mx[t]=min(mx[t], arr[t]);
if(arr[t] && f[t]) arr[f[t]]=l[f[t]];
arr[t]=0;
}
}
int getans() {
int ret=0;
for1(i, 1, cnt) ret=max(ret, mx[i]);
return ret;
}
}a; const int N=100005;
char s[N];
int main() {
scanf("%s", s);
a.build(s);
while(~scanf("%s", s)) a.find(s);
print(a.getans());
return 0;
}

  


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

【SPOJ】1812. Longest Common Substring II(后缀自动机)的更多相关文章

  1. SPOJ LCS2 - Longest Common Substring II 后缀自动机 多个串的LCS

    LCS2 - Longest Common Substring II no tags  A string is finite sequence of characters over a non-emp ...

  2. SPOJ LCS2 Longest Common Substring II ——后缀自动机

    后缀自动机裸题 #include <cstdio> #include <cstring> #include <iostream> #include <algo ...

  3. 【SPOJ】Longest Common Substring(后缀自动机)

    [SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...

  4. 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 s ...

  5. SPOJ 1812 Longest Common Substring II

    A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...

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

    [题目链接] http://www.spoj.com/problems/LCS2/ [题目大意] 求n个串的最长公共子串 [题解] 对一个串建立后缀自动机,剩余的串在上面跑,保存匹配每个状态的最小值, ...

  7. SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机、状压DP)

    手动博客搬家: 本文发表于20181217 23:54:35, 原地址https://blog.csdn.net/suncongbo/article/details/85058680 人生第一道后缀自 ...

  8. [SPOJ1812]Longest Common Substring II 后缀自动机 多个串的最长公共子串

    题目链接:http://www.spoj.com/problems/LCS2/ 其实两个串的LCS会了,多个串的LCS也就差不多了. 我们先用一个串建立后缀自动机,然后其它的串在上面跑.跑的时候算出每 ...

  9. SPOJ LCS Longest Common Substring(后缀自动机)题解

    题意: 求两个串的最大\(LCS\). 思路: 把第一个串建后缀自动机,第二个串跑后缀自动机,如果一个节点失配了,那么往父节点跑,期间更新答案即可. 代码: #include<set> # ...

  10. 【SPOJ】Longest Common Substring II (后缀自动机)

    [SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...

随机推荐

  1. HDU 1176免费馅饼 DP数塔问题转化

    L - 免费馅饼 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Sta ...

  2. mysql将int 时间类型格式化

    摘要 DATE_FORMAT(date,format) 根据format字符串安排date值的格式. DATE_FORMAT(date,format)  根据format字符串安排date值的格式. ...

  3. Dan计划:重新定义人生的10000个小时

    一. 1985年,芝加哥大学的Benjamin Bloom教授,出版了一本重要著作<如何培养天才>(Developing Talent in Young People). 他研究的是,如何 ...

  4. 【Spring】Spring系列7之Spring整合MVC框架

    7.Spring整合MVC框架 7.1.web环境中使用Spring 7.2.整合MVC框架 目标:使用Spring管理MVC的Action.Controller 最佳实践参考:http://www. ...

  5. ENGINE=InnoDB

    最开始用MySQL Administrator建数据库的时候,表缺省是InnoDB类型,也就没有在意.后来用Access2MySQL导数据的时候发现只能导成 MyISAM类型的表 区别如下原来是MyI ...

  6. nginx服务器的网站权限问题

    有时候我们的网站根目录会从一个目录迁移到另一个目录,如果我们服务器使用的是nginx或者Apache,我们一般会配置好网站根目录后然后往直接把网站解压或者上传到根目录中,这样引起的问题是无法对对文件进 ...

  7. MFC RadioButton

    添加一组RadioButton 多个radio button,IDC_RADIO1,IDC_RADIO2,IDC_RADIO3 ..将IDC_RADIO1的Group属性选择上,其他不要选Group属 ...

  8. zsh(yum装包的时候,有时候会不行)

    [root@GIT ~]# yum search zsh =============================== N/S Matched: zsh ====================== ...

  9. Android打Path的方法

    转自:http://blog.csdn.net/xiangzi10/article/details/42710099 作为程序员,了解diff&patch命 令是非常必要的.比如说我们发现某个 ...

  10. hdu 1005:Number Sequence(水题)

    Number Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...