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 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)的更多相关文章
- 【SPOJ】Longest Common Substring(后缀自动机)
[SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...
- 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 ...
- 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 ...
- SPOJ 1812 Longest Common Substring II(后缀自动机)
[题目链接] http://www.spoj.com/problems/LCS2/ [题目大意] 求n个串的最长公共子串 [题解] 对一个串建立后缀自动机,剩余的串在上面跑,保存匹配每个状态的最小值, ...
- SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机、状压DP)
手动博客搬家: 本文发表于20181217 23:54:35, 原地址https://blog.csdn.net/suncongbo/article/details/85058680 人生第一道后缀自 ...
- SPOJ LCS2 Longest Common Substring II ——后缀自动机
后缀自动机裸题 #include <cstdio> #include <cstring> #include <iostream> #include <algo ...
- [SPOJ1812]Longest Common Substring II 后缀自动机 多个串的最长公共子串
题目链接:http://www.spoj.com/problems/LCS2/ 其实两个串的LCS会了,多个串的LCS也就差不多了. 我们先用一个串建立后缀自动机,然后其它的串在上面跑.跑的时候算出每 ...
- SPOJ LCS Longest Common Substring(后缀自动机)题解
题意: 求两个串的最大\(LCS\). 思路: 把第一个串建后缀自动机,第二个串跑后缀自动机,如果一个节点失配了,那么往父节点跑,期间更新答案即可. 代码: #include<set> # ...
- 【SPOJ】Longest Common Substring II (后缀自动机)
[SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...
随机推荐
- ndk-build 学习笔记
# 必须以local_path 开头# 定位源文件LOCAL_PATH := $(call my-dir) #引入clear-vars.mk文件,清除除local_path以外的其他local_< ...
- Oracle树形结构数据---常见处理情景
Oracle树形结构数据---常见处理情景 1.查看表数据结构 SELECT * FROM QIANCODE.TREE_HIS_TABLE T ORDER BY T.NODE_LEVEL; ...
- 魔板 Magic Squares(广搜,状态转化)
题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 我们知道魔板的每一个方格都有一种颜色.这8种颜 ...
- XAMPP中的MySQL与本地MySQL冲突的问题
学习SQL时在本地中先安装了MySQL,后来因为项目需要又安装了XAMPP集成环境,今天在启动项目的时候发现启动MySQL各种问题(期望启动的是XAMPP中的MySQL服务),在Navicat中显示成 ...
- 前端pc版的简单适配
我们都知道对于前端pc版本的适配是一个难题,大部分都是做的媒体查询.但是有时间公司不要媒体查询 就是需要不管多大的屏幕都是满屏显示.我就在考虑为啥不用rem给pc端做个适配. 我是基于设计图是1920 ...
- C语言关于指针的注意事项
一.指针的四个关键概念1.指针的类型2.指针指向的类型3.指针的值,也就是指针指向的地址4.指针自己所占用的内存空间注意:指针变量所存的内容就是内存的地址编号! 例如:int **pp = NULL; ...
- 为什么不早点使用 Git...
教程:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013739628770 ...
- java服务端项目开发规范
更新内容 2015-03-13 (请先更新svn的mybatis.xml.BaseMapper.java.Pager.java文件) 加入测试类规范 加入事物控制规范 加入mapper接口规则 ...
- python3 练习题100例 (二十八)打印一定范围内的素数
题目内容: 给定一个大于2的正整数n,打印出小于n(不包括n且n不大于100)的所有素数. 要求将符合条件的输出填入一个列表中,打印的结果为该列表. 输入格式: 共一行,为一个大于2的正整数 输出格式 ...
- C语言实例解析精粹学习笔记——31
实例31: 判断字符串是否是回文 思路解析: 引入两个指针变量(head和tail),开始时,两指针分别指向字符串的首末字符,当两指针所指字符相等时,两指针分别向后和向前移动一个字符位置,并继续比较, ...