题链:

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

后缀自动机。
对第一个串建立后缀自动机,
然后把后面的每个串分别与该串的自动机去匹配,求出相应的数组val*[s]:
表示第*个串与第一个串的自动机的状态s的最大匹配长度,

(求法就是两个串用后缀自动机求LCS这一过程):
对于当前已经匹配的子串T,长度为now,此刻在状态s,现在要匹配第i个字符x,
若trans(s,x)!=0,则s=trans(s,x),now++,i++,并更新val*[s]=max(val*[s],now);
否则,s=parent[s],直到trans(s,x)!=0或者s=0。
由于我们在每一步更新s时,没有更新到其祖先,所以最后再桶排之后去依次更新父亲。

而最后的状态s和每个串的最大匹配长度就是min(min(val*[s]),maxs[s](这个是状态s所允许的最大长度));

代码:

#include<bits/stdc++.h>
#define MAXN 100005
#define INF 0x3f3f3f3f
using namespace std;
struct SAM{
int size,last,lens;
int maxs[MAXN*3],trans[MAXN*3][26],parent[MAXN*3],minmatch[MAXN*3];
int Newnode(int a,int b){
++size; maxs[size]=a; minmatch[size]=INF;
memcpy(trans[size],trans[b],sizeof(trans[b]));
return size;
}
void Extend(int x){
static int p,np,q,nq;
p=last; last=np=Newnode(maxs[p]+1,0);
for(;p&&!trans[p][x];p=parent[p]) trans[p][x]=np;
if(!p) parent[np]=1;
else{
q=trans[p][x];
if(maxs[p]+1!=maxs[q]){
nq=Newnode(maxs[p]+1,q);
parent[nq]=parent[q];
parent[q]=parent[np]=nq;
for(;p&&trans[p][x]==q;p=parent[p]) trans[p][x]=nq;
}
else parent[np]=q;
}
}
void Build(char *S){
memset(trans[0],0,sizeof(trans[0]));
size=0; last=Newnode(0,0); lens=strlen(S);
for(int i=0;i<lens;i++) Extend(S[i]-'a');
}
void Update(int *val){
static int tmp[MAXN],order[MAXN*3];
memset(tmp,0,sizeof(tmp));
for(int p=1;p<=size;p++) tmp[maxs[p]]++;
for(int i=1;i<=lens;i++) tmp[i]+=tmp[i-1];
for(int p=1;p<=size;p++) order[tmp[maxs[p]]--]=p;
for(int i=size,p;i;i--)
p=order[i],val[parent[p]]=max(val[parent[p]],val[p]);
}
void Match(char *T){
static int val[MAXN*3],p,i,len,now;
for(p=1;p<=size;p++) val[p]=0;
p=1; i=0; now=0; len=strlen(T);
while(i<len){
if(!p) p=1,now=0,i++;
else if(!trans[p][T[i]-'a']) p=parent[p],now=maxs[p];
else now++,p=trans[p][T[i]-'a'],i++;
val[p]=max(val[p],now);
}
Update(val);
for(p=1;p<=size;p++) minmatch[p]=min(minmatch[p],val[p]);
}
}SUF;
int main(){
static char S[MAXN];
scanf("%s",S); SUF.Build(S);
while(~scanf("%s",S)) SUF.Match(S);
int ans=0;
for(int p=1;p<=SUF.size;p++)
ans=max(ans,min(SUF.minmatch[p],SUF.maxs[p]));
printf("%d\n",ans);
return 0;
}

  

●SPOJ LCS2Longest Common Substring II的更多相关文章

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

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

  2. 2018.12.15 spoj Longest Common Substring II(后缀自动机)

    传送门 后缀自动机基础题. 给出10个串求最长公共子串. 我们对其中一个建一个samsamsam,然后用剩下九个去更新范围即可. 代码: #include<bits/stdc++.h> # ...

  3. SPOJ Longest Common Substring II

    题目连接:戳我 题目大意:求n个字符串的最长公共子串. 它的简化版--这里 当然我们可以用SA写qwq,也可以用广义SAM写qwq 这里介绍纯SAM的写法...就是对其中一个建立后缀自动机,然后剩下的 ...

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

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

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

    spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 < ...

  6. 【SPOJ】Longest Common Substring II

    [SPOJ]Longest Common Substring II 多个字符串求最长公共子串 还是将一个子串建SAM,其他字符串全部跑一边,记录每个点的最大贡献 由于是所有串,要对每个点每个字符串跑完 ...

  7. SPOJ LCS2 - Longest Common Substring II

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

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

  9. Longest Common Substring II SPOJ - LCS2 (后缀自动机)

    Longest Common Substring II \[ Time Limit: 236ms\quad Memory Limit: 1572864 kB \] 题意 给出\(n\)个子串,要求这\ ...

随机推荐

  1. C作业--数据类型

    一.PTA实验作业 题目1:7-3 倒顺数字串 1. 本题PTA提交列表 2. 设计思路(伪代码) (1)本题是要求输入倒顺序数串,首先看到这种题肯定是需要用到循环,那就先定一个整形i来进行循环,n是 ...

  2. 冲刺NO.2

    Alpha冲刺第二天 站立式会议 项目进展 团队成员在确定了所需技术之后,开始学习相关技术的使用,其中包括了HTML5,CSS与SSH框架等开发技术.并且在项目分工配合加以总结和完善,对现有发现的关于 ...

  3. 单向链表在O(1)时间内删除一个节点

    说删链表节点,第一时间想到就是遍历整个链表,找到删除节点的前驱,改变节点指向,删除节点,但是,这样删除单链表的某一节点,时间复杂度就是O(n),不符合要求: 时间复杂度是O(n)的做法就不说了,看看O ...

  4. 织梦cms/dedecms清理冗余废弃未引用图片方法

    原理描述: 在原有织梦后台菜单中增加"清理冗余图片按钮",实现清理冗余图片的功能. 操作步骤: 1. 打开后台dede\sys_sql_query.php代码 在该文件中搜索如下代 ...

  5. PC或者手机弹出窗效果

    http://layer.layui.com/ 这个网站提供弹窗,是在jq封装的,弹窗之后,背景页面还可以滑动. 这个里面的js可能也会包含css,这个css不能移动位置,否则会报错,还有谷歌浏览器在 ...

  6. Oracle数据库游标精解

    游标 定义:标识结果集中数据行的一种容器(CURSOR),游标允许应用程序对查询语句返回的行结果集中的每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作.实际上是一种能从包括多条数据记录 ...

  7. 电子称DIY(贴应变片+写代码)

    第一步.应变片介绍   ---------------------------------------------------------------------------------------- ...

  8. New UWP Community Toolkit - DropShadowPanel

    概述 UWP Community Toolkit  中有一个为 Frmework Element 提供投影效果的控件 - DropShadowPanel,本篇我们结合代码详细讲解  DropShado ...

  9. redis入门(05)redis的key命令

    一.什么是redis键命令 Redis 键(key):Redis 键命令用于管理 redis 的键. Redis 键命令的基本语法: redis 127.0.0.1:6379> COMMAND ...

  10. IDE-Ecplise-代码注释 模版 编码规范 配色

    说明: 代码注释主要用于方便代码后期维护,编码规范,增加代码阅读性和维护性.因网上看到的很多博客中片段局多,故整理后重写一篇,方便交流学习. 先看下加过注释模版后的效果. 如上图所示,创建类,方法和继 ...