Longest Common Substring

题意

求两个串的最长公共子串。

分析

第一个串建后缀自动机,第二个串在自动机上跑,对于自动机上的结点(状态)而言,它所代表的最大长度为根结点到当前结点的长度,而它的前继结点的串一定是这个结点串的后缀串(或空串)。

匹配过程中一旦失配,自动机上的结点找它的前继结点,继续向后匹配即可。

code

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 250005;
char s[MAXN]; /* 性质:
① 从root到任意结点p的每条路径上的字符组成的字符串,都是当前串t的子串
② 因为满足性质一,所以如果当前结点p是可以接收新后缀的结点,那么从root到任意结点p的每条路径上的字符组成的字符串,都是必定是当前串t的后缀
③ 如果结点p可以接收新的后缀,那么p的fa指向的结点也可以接收后缀,反过来就不行
从 root 出发的任何子串最终都会到达一个合法状态,而非子串最终都会“无路可走”
*/
struct SAM {
int ch[MAXN << 1][26];
int fa[MAXN << 1]; // 前继结点,如果当前结点可以接受某个后缀那么它的前继结点也可以接受
int len[MAXN << 1]; // 从根结点到该结点的最大距离,这个状态(结点)代表的串长度区间 (len[fa], len]
int cnt, last;
void init() {
memset(ch, 0, sizeof ch);
memset(fa, 0, sizeof fa);
last = cnt = 1; // root节点为 1 ,所以添加的字符从 2 开始
}
void add(int c) {
int p = last, np = last = ++cnt;
len[np] = len[p] + 1;
while(!ch[p][c] && p) {
ch[p][c] = np;
p = fa[p];
}
if(p == 0) fa[np] = 1;
else {
int q = ch[p][c];
if(len[p] + 1 == len[q]) { // p、q之间无其他结点
fa[np] = q;
} else { // np的加入导致前面某个结点的状态发生改变
int nq = ++cnt;
len[nq] = len[p] + 1;
memcpy(ch[nq], ch[q], sizeof ch[q]);
fa[nq] = fa[q];
fa[q] = fa[np] = nq;
while(ch[p][c] == q && p) {
ch[p][c] = nq;
p = fa[p];
}
}
}
}
} sam; int main() {
scanf("%s", s);
int len = strlen(s);
sam.init();
for(int i = 0; i < len; i++) {
sam.add(s[i] - 'a');
}
scanf("%s", s);
len = strlen(s);
int p = 1;
int ans = 0;
int c = 0;
for(int i = 0; i < len; ) {
while(sam.ch[p][s[i] - 'a']) {
p = sam.ch[p][s[i] - 'a'];
i++;
c++;
}
ans = max(ans, c);
if(!c) i++;
else {
p = sam.fa[p];
c = sam.len[p];
}
}
printf("%d\n", ans);
return 0;
}

spoj - Longest Common Substring(后缀自动机模板题)的更多相关文章

  1. SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)

    题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...

  2. hdu 1403 Longest Common Substring 后缀数组 模板题

    题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...

  3. SPOJ1811 LCS - Longest Common Substring(后缀自动机)

    A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...

  4. SPOJ 1811 Longest Common Substring 后缀自动机

    模板来源:http://www.neroysq.com/?p=76 思路:http://blog.sina.com.cn/s/blog_7812e98601012dfv.html 题意就是求两个字符串 ...

  5. [SPOJ1811]Longest Common Substring 后缀自动机 最长公共子串

    题目链接:http://www.spoj.com/problems/LCS/ 题意如题目,求两个串的最大公共子串LCS. 首先对其中一个字符串A建立SAM,然后用另一个字符串B在上面跑. 用一个变量L ...

  6. 牛客网 桂林电子科技大学第三届ACM程序设计竞赛 A.串串-后缀自动机模板题

    链接:https://ac.nowcoder.com/acm/contest/558/A来源:牛客网 A.串串 小猫在研究字符串. 小猫在研究字串. 给定一个长度为N的字符串S,问所有它的子串Sl…r ...

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

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

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

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

  9. spoj 1811 LCS - Longest Common Substring (后缀自己主动机)

    spoj 1811 LCS - Longest Common Substring 题意: 给出两个串S, T, 求最长公共子串. 限制: |S|, |T| <= 1e5 思路: dp O(n^2 ...

随机推荐

  1. 51nod 1680区间求和 (dp+树状数组/线段树)

    不妨考虑已知一个区间[l,r]的k=1.k=2....k=r-l+1这些数的答案ans(只是这一个区间,不包含子区间) 那么如果加入一个新的数字a[i](i = r+1) 则新区间[l, i]的答案为 ...

  2. 【HDU 4300 Clairewd’s message】

    Clairewd is a member of FBI. After several years concealing in BUPT, she intercepted some important ...

  3. ubuntu下使用sudo 出现unable to resolve host 解决方法

    Linux 环境, 假设这台机器名字叫dev(机器的hostname), 每次执行sudo 就出现这个警告讯息:sudo: unable to resolve host dev虽然sudo 还是可以正 ...

  4. [poj 3252]数位dp前导0的处理

    通过这个题对于数位dp中前导0的处理有了新的认识. 题目链接:http://poj.org/problem?id=3252 //http://poj.org/problem?id=3252 #incl ...

  5. idea中mybatis-plugin破解

    Mybatis Plugin 一.Mybatis Plugin插件是什么 提供Mapper接口与配置文件中对应SQL的导航 编辑XML文件时自动补全 根据Mapper接口, 使用快捷键生成xml文件及 ...

  6. linux网络编程系列-TCP/IP模型

    ### OSI:open system interconnection ### 开放系统互联网模型是由ISO国际标准化组织定义的网络分层模型,共七层 1. 物理层:物理定义了所有电子及物理设备的规范, ...

  7. ES6学习笔记(四)—— async 函数

    await 是 async wait 的简写, 是 generator 函数的语法糖. async 函数的特点: async 声明一个方法是异步的,await 则等待这个异步方法执行的完成 async ...

  8. cmd常用命令行

    新建文件夹或文件 打开磁盘     F: 退出cmd     exit 返回上一级     cd.. 创建文件夹     md 文件夹名 在d盘创建文件夹     md d:\文件夹名 在当前目录打开 ...

  9. js实现2048小游戏

    这是学完javascript基础,编写的入门级web小游戏 游戏规则:在玩法规则也非常的简单,一开始方格内会出现2或者4等这两个小数字,玩家只需要上下左右其中一个方向来移动出现的数字,所有的数字就会想 ...

  10. finally return 执行顺序问题

    网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行?很多人都说不是,当然他们的回答是正确的,经过我试验,至少有两种情况下fina ...