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的更多相关文章

  1. 【spoj LCS2】 Longest Common Substring II

    http://www.spoj.com/problems/LCS2/ (题目链接) 题意 求多个串的最长公共子串 Solution 对其中一个串构造后缀自动机,然后其它串在上面跑匹配.对于每个串都可以 ...

  2. 【SPOJ - LCS2】Longest Common Substring II【SAM】

    题意 求出多个串的最长公共子串. 分析 刚学SAM想做这个题的话最好先去做一下那道codevs3160.求两个串的LCS应该怎么求?把一个串s1建自动机,然后跑另一个串s2,然后找出s2每个前缀的最长 ...

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

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

  4. 【刷题】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 ...

  5. SPOJ 1812 LCS2 - Longest Common Substring II

    思路 后缀自动机求多串的最长公共子串 对第一个建出后缀自动机,其他的在SAM上匹配,更新到一个节点的匹配长度最大值即可,最后对所有最大值取min得到一个节点的答案,对所有节点答案求max即可 然后注意 ...

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

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

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

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

  8. 【SPOJ】Longest Common Substring II

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

  9. 【hdu 1403】Longest Common Substring

    [链接]h在这里写链接 [题意] 求两个串的最长公共子串. [题解] Sa[i]表示的是字典序为i的后缀的起始位置. 可以把两个字符串合在一起(中间用一个比'z'大的字符分割); 则如果Sa[i-1] ...

随机推荐

  1. 《2016ThoughtWorks技术雷达峰会----变革的原因》

    变革的原因      张松 ,ThoughtWorks中国区总经理 首先回顾IT历史,观点如下: 1.在80,90年代,IT作为一个种生产效率的提高工具,主要是把手工的活动自动化.以client se ...

  2. 单机搭建Android开发环境(三)

    单机搭建Android开发环境,第一篇重点介绍了如何优化Windows 7系统,以提高开发主机的性能并延长SSD的使用寿命.第二篇重点介绍了基于VMWare安装64位版的Ubuntu 12.04,并安 ...

  3. POJ3187Backward Digit Sums[杨辉三角]

    Backward Digit Sums Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6350   Accepted: 36 ...

  4. C#复习(学生信息输入)

    在控制台程序中使用结构体.集合,完成下列要求项目要求:一.连续输入5个学生的信息,每个学生都有以下4个内容:1.序号 - 根据输入的顺序自动生成,不需要手动填写,如输入第一个学生的序号是1,第二个是2 ...

  5. luogu1097统计数字[noip2007提高组Day1T1]

    题目描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*10^9).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出 ...

  6. View.inflate和LayoutInflater的inflate方法区别

    平时ListView加载item中,adapter的getView方法中,我们经常用到: LayoutInflater.from(mContext).inflate(R.layout.it ,pare ...

  7. iOS中NSScanner 的用法

    NSScanner是一个类,用于在字符串中扫描指定的字符,尤其是把它们翻译/转换为数字和别的字符串.可以创建NSScanner时制定他的String属性,然后scanner会按照你的要求从头到尾扫描这 ...

  8. 改变input默认选中颜色

    修改 outline-color 属性即可实现

  9. php 中的curl

    ① curl上传文件 <?php $postData=array( 'name'=>'123', 'upload'=>'@E:/wamp/www/function/result.zi ...

  10. python学习之用正则处理log(持续更新,ftace)

    1. ftrace的输出如下图所示: [003] 48375.494595: clear_buddies <-pick_next_entity m=re.match("^\[([0-9 ...