Longest Common Substring II

给定n个串,求它们的最长公共子串。

at most 10 lines,no more than 100000

iwt的题解

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

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

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

比如数据

acbbc

bc

ac

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

这个多想想就行了。

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

时间复杂度:线性。

co int N=2e5;
namespace SAM
{
int tot,last;
int ch[N][26],fail[N]={-1},len[N];
void extend(int k)
{
int cur=++tot;
len[cur]=len[last]+1;
int p=last;
while(~p&&!ch[p][k])
{
ch[p][k]=cur;
p=fail[p];
}
if(p==-1)
fail[cur]=0;
else
{
int q=ch[p][k];
if(len[q]==len[p]+1)
fail[cur]=q;
else
{
int clone=++tot;
std::copy(ch[q],ch[q]+26,ch[clone]);
fail[clone]=fail[q],len[clone]=len[p]+1;
while(~p&&ch[p][k]==q)
{
ch[p][k]=clone;
p=fail[p];
}
fail[cur]=fail[q]=clone;
}
}
last=cur;
}
int c[N],id[N],mx[N],arr[N];
void build(char s[],int n)
{
for(int i=0;i<n;++i)
extend(s[i]-'a');
for(int i=0;i<=tot;++i)
++c[len[i]];
for(int i=1;i<=n;++i)
c[i]+=c[i-1];
for(int i=0;i<=tot;++i)
id[--c[len[i]]]=i; // edit 1:--c for 0
std::copy(len,len+tot+1,mx);
}
void find(char s[],int n)
{
int p=0,l=0;
for(int i=0;i<n;++i)
{
int k=s[i]-'a';
if(ch[p][k])
p=ch[p][k],++l;
else
{
while(~p&&!ch[p][k])
p=fail[p];
if(p==-1)
p=l=0;
else
l=len[p]+1,p=ch[p][k];
}
arr[p]=std::max(arr[p],l);
}
for(int i=tot;i>=0;--i)
{
int p=id[i];
mx[p]=std::min(mx[p],arr[p]);
if(arr[p]&&fail[p])
arr[fail[p]]=len[fail[p]];
arr[p]=0;
}
}
int getans()
{
int ans=0;
for(int i=0;i<=tot;++i)
ans=std::max(ans,mx[i]);
return ans;
}
}
char buf[N]; int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
scanf("%s",buf);
SAM::build(buf,strlen(buf));
while(~scanf("%s",buf))
SAM::find(buf,strlen(buf));
printf("%d\n",SAM::getans());
return 0;
}

SPOJ1812 Longest Common Substring II的更多相关文章

  1. SPOJ1812 - Longest Common Substring II(LCS2)

    Portal,Portal to 洛谷 Description 给出\(n(n\leq10)\)个仅包含小写字母的字符串\(s_1..s_n(|s_i|\leq10^5)\),求这些字符串的最长公共子 ...

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

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

  3. spoj1812 LCS2 - Longest Common Substring II

    地址:http://www.spoj.com/problems/LCS2/ 题面: LCS2 - Longest Common Substring II no tags  A string is fi ...

  4. SPOJ1812 LCS2 - Longest Common Substring II【SAM LCS】

    LCS2 - Longest Common Substring II 多个字符串找最长公共子串 以其中一个串建\(SAM\),然后用其他串一个个去匹配,每次的匹配方式和两个串找\(LCS\)一样,就是 ...

  5. SPOJ LCS2 - Longest Common Substring II

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

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

    Longest Common Substring II Time Limit: 2000ms Memory Limit: 262144KB A string is finite sequence of ...

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

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

  8. 【SP1812】LCS2 - Longest Common Substring II

    [SP1812]LCS2 - Longest Common Substring II 题面 洛谷 题解 你首先得会做这题. 然后就其实就很简单了, 你在每一个状态\(i\)打一个标记\(f[i]\)表 ...

  9. 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 ...

随机推荐

  1. 【转载】User notification 的实现方法

    原帖请看:http://cocoathings.blogspot.com/2013/01/introduction-to-user-notifications-in.html 想要实现如图这样的not ...

  2. kafka和canal设置为开机启动

    1.切换到初始化目录 cd /etc/init.d/ 2.新建一个文件 如 touch autoupdate 3.vim autoupdate #!/bin/bash export JAVA_HOME ...

  3. 【bzoj1009】[HNOI2008]GT考试(矩阵快速幂优化dp+kmp)

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1009 这道题一看数据范围:$ n<=10^9 $,显然不是数学题就是矩乘快速幂优 ...

  4. Android--第三方控件--okHttp

    Android中有很多的第三方控件,其中OkHttp是一个很强大的用于网络加载的第三方框架,当然了,它的内部也是使用原生的代码封装好的.今天我们就来看一下OkHttp的简单用法: 说到网络请求,肯定就 ...

  5. caffe2 教程入门(python版)

    学习思路 1.先看官方文档,学习如何使用python调用caffe2包,包括 Basics of Caffe2 - Workspaces, Operators, and Nets Toy Regres ...

  6. base64编码的 文件 图片

    //图片 转为 base64编码的文本 private void button1_Click(object sender, EventArgs e) { OpenFileDialog dlg = ne ...

  7. 为什么font-size推荐使用具体数值?

    1.font-size的单位 font-size通常用的单位是px/em/rem,px就不说了,em/rem 主要用在移动端,原因的根据根元素大小进行适配,简而言之,em相对于父级定义基础字号,rem ...

  8. poj3311 状压dp+floyd

    先floyd预处理一遍dis,枚举所有状态,dp[ i ] [ j ]表示 以  j  为终点的状态 i 使用最小的时间 #include<map> #include<set> ...

  9. Cassandra二级索引原理——新创建了一张表格,同时将原始表格之中的索引字段作为新索引表的Primary Key,并且存储的值为原始数据的Primary Key,然后再通过pk一级索引找到真正的值

    1.什么是二级索引? 我们前面已经介绍过Cassandra之中有各种Key,比如Primary Key, Cluster Key 等等.如果您对这部分概念并不熟悉,可以参考之前的文章: [Cassan ...

  10. Hibernate中Hql查询

    这篇随笔将会记录hql的常用的查询语句,为日后查看提供便利. 在这里通过定义了三个类,Special.Classroom.Student来做测试,Special与Classroom是一对多,Class ...