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.

题目大意:求多个字符串的最长公共子串。

思路:据说把多个串拼起来会MLE还是TLE?SPOJ太慢了……

给第一个串建立后缀自动机,然后把每个点的ans置为当前后缀的LCS,dp为当前某个串能匹配的最长后缀

然后每次弄完用每个点的dp更新ans……图是一个DAG……

哎呀好难说看代码吧……

代码(1500MS):

 #include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std; const int MAXN = + ;
char buf[MAXN];
struct State {
State *fail, *go[];
int val, dp, ans;/*
State() :
fail(0), val(0) {
memset(go, 0, sizeof go);
}*/
}*root, *last;
State statePool[MAXN * ], *cur; void init() {
//memset(statePool, 0, 2 * strlen(buf) * sizeof(State));
cur = statePool;
root = last = cur++;
} void extend(int w) {
State *p = last, *np = cur++;
np->ans = np->val = p->val + ;
while (p && !p->go[w])
p->go[w] = np, p = p->fail;
if (!p) np->fail = root;
else {
State*q = p->go[w];
if (p->val + == q->val) np->fail = q;
else {
State *nq = cur++;
memcpy(nq->go, q->go, sizeof q->go);
nq->ans = nq->val = p->val + ;
nq->fail = q->fail;
q->fail = nq;
np->fail = nq;
while (p && p->go[w] == q)
p->go[w] = nq, p = p->fail;
}
}
last = np;
} inline void update_max(int &a, const int &b) {
if(a < b) a = b;
} inline void update_min(int &a, const int &b) {
if(a > b) a = b;
} struct Node {
State *p;
bool operator < (const Node &rhs) const {
return p->val < rhs.p->val;
}
} a[MAXN * ]; int main() {
init();
scanf("%s", buf);
for(char *pt = buf; *pt; ++pt)
extend(*pt - 'a');
int m = ;
for(State *p = statePool; p != cur; ++p) {
a[m++].p = p;
}
sort(a, a + m);
int n = ;
while(scanf("%s", buf) != EOF) {
++n;
State *t = root;
int l = ;
for(char *pt = buf; *pt; ++pt) {
int w = *pt - 'a';
if(t->go[w]) {
t = t->go[w];
update_max(t->dp, ++l);
}
else {
while(t && !t->go[w]) t = t->fail;
if(!t) l = , t = root;
else {
l = t->val;
t = t->go[w];
update_max(t->dp, ++l);
}
}
}
for(int i = m - ; i > ; --i) {
State *p = a[i].p;
update_min(p->ans, p->dp);
update_max(p->fail->dp, min(p->dp, max(p->fail->val, p->dp)));
p->dp = ;
}
}
int ans = ;
for(int i = m - ; i >= ; --i) update_max(ans, a[i].p->ans);
printf("%d\n", ans);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. block与inline,inline和inline-block,块级和行内元素,行内替换和行内非替换元素

    block:块级元素默认display属性为block:无论块内内容有多少,总是占满一行: inline:行内元素默认display属性为inline:只占据块内的内容的大小,不会占满一整行: inl ...

  2. 菜鸟笔记 -- Chapter 6.4.2 详解继承

    6.4.2  详解继承 6.4.2.1  继承入门 继承使得程序架构具有一定的弹性,在程序中复用一些已经定义完善的类不仅可以减少软件开发周期,也可以提高软件的可维护性和可扩展性.基本思想是基于某个父类 ...

  3. idea开启自动编译

    springboot+thymeleaf+idea   idea默认是不自动编译的. 首先热部署的jar包肯定是要加进去的 2,快捷键 ctrl+shift+alt+/       点击registr ...

  4. spring入门学习感悟

    1:ioc:控制反转 控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是有外部容器负责创建和维护的(获取依赖对象的过程被反转了) 2:di:依赖注入,它是一种控制反转的一种实现方法,ioc容器 ...

  5. 在C++中如何实现文件的读写

    一.ASCII 输出为了使用下面的方法, 你必须包含头文件<fstream.h>(译者注:在标准C++中,已经使用<fstream>取代< fstream.h>,所 ...

  6. java 读取图片并转化为二进制字符串

    本例子的目的在于测试往oracle数据库中插入blob字段 //以下代码源于:https://www.cnblogs.com/ywlx/p/4544179.html public static Str ...

  7. oracle优化-leading提示和ordered提示以及materialize提示

    以下内容适用于oracle 10.2.0.5及其以上版本 一个查询很慢,原始SQL如下: select a.* from (select ssi.ID, 'small_station_info' TB ...

  8. 配置django控制台输出ORM转化的sql

    在setting中配置 LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ ' ...

  9. CentOS 7 以上防火墙简单配置

    CentOS 7 版本以上默认的防火墙不是iptables,而是firewalle. 因此CentOS 7 以下的 iptables 的配置不能使用. 查看防火墙状态: systemctl statu ...

  10. CentOS7版本基础使用

    第1章 CentOS7的使用 1.1 为什么要使用CentOS7版本 CentOS7是在CentOS6基础上发布的新版本,与之前的版本相比,主要的更新包括: 1.内核更新到3.10.0 2.支持Lin ...