【SPOJ 1812】Longest Common Substring II
http://www.spoj.com/problems/LCS2/
这道题想了好久。
做法是对第一个串建后缀自动机,然后用后面的串去匹配它,并在走过的状态上记录走到这个状态时的最长距离。每匹配完一个串要对每个状态往它的parent更新,因为状态记录的最长距离一定大于parent的val值,所以parent的最长距离直接赋为val即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct State {
State *par, *go[26];
int val, mn, now;
} *root, *last, pool[250003], *id[250003];
int tot = 0;
State *newState(int _val) {
State *t = &pool[++tot];
t->par = 0; t->val = t->now = 0;
memset(t->go, 0, sizeof(t->go));
t->mn = t->val = _val;
return t;
}
void extend(int w) {
State *p = last;
State *np = newState(p->val + 1);
while (p && p->go[w] == 0)
p->go[w] = np, p = p->par;
if (p == 0) np->par = root;
else {
State *q = p->go[w];
if (q->val == p->val + 1) np->par = q;
else {
State *nq = newState(p->val + 1);
memcpy(nq->go, q->go, sizeof(q->go));
nq->par = q->par;
q->par = np->par = nq;
while (p && p->go[w] == q)
p->go[w] = nq, p = p->par;
}
}
last = np;
}
int len, c[100003];
char s[100003];
int main() {
root = last = newState(0);
scanf("%s", s + 1);
len = strlen(s + 1);
for(int i = 1; i <= len; ++i)
extend(s[i] - 'a');
for(int i = 1; i <= tot; ++i)
++c[pool[i].val];
for(int i = 1; i <= len; ++i)
c[i] += c[i - 1];
for(int i = tot; i >= 1; --i)
id[c[pool[i].val]--] = &pool[i];
State *tmp; int now, x;
while (~scanf("%s", s + 1)) {
len = strlen(s + 1);
tmp = root; now = 0;
for(int i = 1; i <= len; ++i) {
x = s[i] - 'a';
if (tmp->go[x]) {
tmp = tmp->go[x];
++now;
} else {
while (tmp && tmp->go[x] == 0)
tmp = tmp->par;
if (tmp == 0) tmp = root, now = 0;
else now = tmp->val + 1, tmp = tmp->go[x];
}
tmp->now = max(tmp->now, now);
}
for(int i = tot; i >= 1; --i) {
tmp = id[i];
tmp->mn = min(tmp->mn, tmp->now);
if (tmp->par != 0 && tmp->now != 0) tmp->par->now = tmp->par->val;
tmp->now = 0;
}
}
int ans = 0;
for(int i = 1; i <= tot; ++i)
ans = max(ans, pool[i].mn);
printf("%d\n", ans);
return 0;
}
【SPOJ 1812】Longest Common Substring II的更多相关文章
- 【spoj LCS2】 Longest Common Substring II
http://www.spoj.com/problems/LCS2/ (题目链接) 题意 求多个串的最长公共子串 Solution 对其中一个串构造后缀自动机,然后其它串在上面跑匹配.对于每个串都可以 ...
- 【SPOJ - LCS2】Longest Common Substring II【SAM】
题意 求出多个串的最长公共子串. 分析 刚学SAM想做这个题的话最好先去做一下那道codevs3160.求两个串的LCS应该怎么求?把一个串s1建自动机,然后跑另一个串s2,然后找出s2每个前缀的最长 ...
- spoj 1812 LCS2 - Longest Common Substring II (后缀自己主动机)
spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 < ...
- 【刷题】SPOJ 1812 LCS2 - 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 LCS2 - Longest Common Substring II
思路 后缀自动机求多串的最长公共子串 对第一个建出后缀自动机,其他的在SAM上匹配,更新到一个节点的匹配长度最大值即可,最后对所有最大值取min得到一个节点的答案,对所有节点答案求max即可 然后注意 ...
- SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机、状压DP)
手动博客搬家: 本文发表于20181217 23:54:35, 原地址https://blog.csdn.net/suncongbo/article/details/85058680 人生第一道后缀自 ...
- 【SPOJ】Longest Common Substring II (后缀自动机)
[SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...
- 【SPOJ】Longest Common Substring II
[SPOJ]Longest Common Substring II 多个字符串求最长公共子串 还是将一个子串建SAM,其他字符串全部跑一边,记录每个点的最大贡献 由于是所有串,要对每个点每个字符串跑完 ...
- 【hdu 1403】Longest Common Substring
[链接]h在这里写链接 [题意] 求两个串的最长公共子串. [题解] Sa[i]表示的是字典序为i的后缀的起始位置. 可以把两个字符串合在一起(中间用一个比'z'大的字符分割); 则如果Sa[i-1] ...
随机推荐
- UVa11549计算器谜题[floyd判圈]
题意: 有个老式计算器,每次只能记住一个数字的前n位.现在输入一个整数k,然后反复平方,一直做下去,能得到的最大数是多少.例如,n=1,k=6,那么一次显示:6,3,9,1... 白书上的题 set, ...
- 平面直接坐标系线段相交问题(小Q(钟神)的问题)
[问题描述] 小 Q 对计算几何有着浓厚的兴趣.他经常对着平面直角坐标系发呆,思考一些有趣的问题.今天,他想到了一个十分有意思的题目:首先,小 Q 会在?轴正半轴和?轴正半轴分别挑选?个点.随后,他将 ...
- VS 的编译选项 build下的 platform target -- Any CPU和x86有什么影响?
VS 的编译选项 build下的platform -- Any CPU和x86有什么影响? 现在的问题是,我的一个assembly用Any CPU编译就不能在64位系统下运行了,但是用x86编译就ok ...
- maven总结5
上篇文章中项目最终发布的release仓库和快照仓库都是nexus的默认仓库,若所有的本地开发项目版本都发布到同一个仓库,可能会造成冲突.因此,我们可以为每一个项目创建一组仓库(快照版本和releas ...
- [No00005F]读书与心智
读千卷书,行万里路,不够…还得有个对谈者相伴,才更有意思.十月七号晚上,与友人谈读书,线上直播,三百观众相伴,四小时畅谈,不亦乐乎! Part1:读书的载体 散发出最浓郁的知识芬芳和铭刻下最隽永的历史 ...
- poj3278 Catch That Cow
Catch That Cow Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 73973 Accepted: 23308 ...
- 在Android中如何获取视频的第一帧图片并显示在一个ImageView中
String path = Environment.getExternalStorageDirectory().getPath(); MediaMetadataRetriever media = n ...
- javascript按回车键触发事件
<form id="search-form" > <input type="text" onkeypress="getKey();r ...
- C语言: 创建数组的几种方法
创建数组有三种方法 1.声明一个数组,声明时用常量表达式指定数组维数,然后可以用数组名访问数组元素 2.声明一个变长数组,声明时用变量表达式指定数组的维数,C99支持 3.声明一个指针,调用mallo ...
- react拷贝index.html很恶心之解决办法
https://www.npmjs.com/package/html-webpack-plugin