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. (转)女生应该找一个玩ACM的男生

    1.强烈的事业心 将来,他也一定会有自己热爱的事业.而且,男人最性感的时刻之一,就是他专心致志做事的时候.所以,找一个机会在他全神贯注玩ACM的时候,从侧面好好观察他,你就会发现我说的话没错. 2.永 ...

  2. python 异步线程简单实现

    import threading def foo(): with open(r'./result.log','wb') as f: f.write('=some logs here ==') t = ...

  3. cobbler部署机器的默认密码

    修改cobbler的默认密码: 用 openssl 生成一串密码后加入到 cobbler 的配置文件(/etc/cobbler/settings)里,替换 default_password_crypt ...

  4. POJ 2386

    http://poj.org/problem?id=2386 这个题目与那个POJ 1562几乎是差不多的,只不过那个比这个输入要复杂一些 #include <stdio.h> #incl ...

  5. mysql 判空

    2013年9月10日 15:44:36 update `zzb_table` set status = 1 where `link` != ''; 不要用 update `zzb_table` set ...

  6. Javascript配合jQuery实现流畅的前端验证

    做前端时一般都习惯用JavaScript进行表单的简单验证比如非空验证和正则表达式验证,这样过滤后的数据提交到服务端再由专门的控制器做数据处理,这样能减轻服务器的负担,下面看一下前端验证的简单步骤: ...

  7. 【xml】python的lxml库使用

    1.官方教程:http://lxml.de/tutorial.html#parsing-from-strings-and-files  最重要的文档,看完基本就能用了 2.lxml支持xpath,xp ...

  8. 【python】异常处理

    转自:http://www.cnblogs.com/IPrograming/p/Python_error_handler.html 1. 抛出异常和自定义异常 Python用异常对象(exceptio ...

  9. python文件取MD5

    import hashlib def md5sum(filename, blocksize=65536): hash = hashlib.md5() with open(filename, " ...

  10. cenos配置

    #修复ifconfig1.查看 /sbin/ifconfig是否存在 echo $PATH2.查看ifconfig命令是否存在ls /sbin |grep ifconfig如果ifconfig命令存在 ...