spoj - Longest Common Substring(后缀自动机模板题)
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(后缀自动机模板题)的更多相关文章
- SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)
题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...
- hdu 1403 Longest Common Substring 后缀数组 模板题
题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...
- SPOJ1811 LCS - Longest Common Substring(后缀自动机)
A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...
- SPOJ 1811 Longest Common Substring 后缀自动机
模板来源:http://www.neroysq.com/?p=76 思路:http://blog.sina.com.cn/s/blog_7812e98601012dfv.html 题意就是求两个字符串 ...
- [SPOJ1811]Longest Common Substring 后缀自动机 最长公共子串
题目链接:http://www.spoj.com/problems/LCS/ 题意如题目,求两个串的最大公共子串LCS. 首先对其中一个字符串A建立SAM,然后用另一个字符串B在上面跑. 用一个变量L ...
- 牛客网 桂林电子科技大学第三届ACM程序设计竞赛 A.串串-后缀自动机模板题
链接:https://ac.nowcoder.com/acm/contest/558/A来源:牛客网 A.串串 小猫在研究字符串. 小猫在研究字串. 给定一个长度为N的字符串S,问所有它的子串Sl…r ...
- 后缀自动机(SAM):SPOJ Longest Common Substring II
Longest Common Substring II Time Limit: 2000ms Memory Limit: 262144KB A string is finite sequence of ...
- 2018.12.15 spoj Longest Common Substring II(后缀自动机)
传送门 后缀自动机基础题. 给出10个串求最长公共子串. 我们对其中一个建一个samsamsam,然后用剩下九个去更新范围即可. 代码: #include<bits/stdc++.h> # ...
- spoj 1811 LCS - Longest Common Substring (后缀自己主动机)
spoj 1811 LCS - Longest Common Substring 题意: 给出两个串S, T, 求最长公共子串. 限制: |S|, |T| <= 1e5 思路: dp O(n^2 ...
随机推荐
- 51nod 1680区间求和 (dp+树状数组/线段树)
不妨考虑已知一个区间[l,r]的k=1.k=2....k=r-l+1这些数的答案ans(只是这一个区间,不包含子区间) 那么如果加入一个新的数字a[i](i = r+1) 则新区间[l, i]的答案为 ...
- 【HDU 4300 Clairewd’s message】
Clairewd is a member of FBI. After several years concealing in BUPT, she intercepted some important ...
- ubuntu下使用sudo 出现unable to resolve host 解决方法
Linux 环境, 假设这台机器名字叫dev(机器的hostname), 每次执行sudo 就出现这个警告讯息:sudo: unable to resolve host dev虽然sudo 还是可以正 ...
- [poj 3252]数位dp前导0的处理
通过这个题对于数位dp中前导0的处理有了新的认识. 题目链接:http://poj.org/problem?id=3252 //http://poj.org/problem?id=3252 #incl ...
- idea中mybatis-plugin破解
Mybatis Plugin 一.Mybatis Plugin插件是什么 提供Mapper接口与配置文件中对应SQL的导航 编辑XML文件时自动补全 根据Mapper接口, 使用快捷键生成xml文件及 ...
- linux网络编程系列-TCP/IP模型
### OSI:open system interconnection ### 开放系统互联网模型是由ISO国际标准化组织定义的网络分层模型,共七层 1. 物理层:物理定义了所有电子及物理设备的规范, ...
- ES6学习笔记(四)—— async 函数
await 是 async wait 的简写, 是 generator 函数的语法糖. async 函数的特点: async 声明一个方法是异步的,await 则等待这个异步方法执行的完成 async ...
- cmd常用命令行
新建文件夹或文件 打开磁盘 F: 退出cmd exit 返回上一级 cd.. 创建文件夹 md 文件夹名 在d盘创建文件夹 md d:\文件夹名 在当前目录打开 ...
- js实现2048小游戏
这是学完javascript基础,编写的入门级web小游戏 游戏规则:在玩法规则也非常的简单,一开始方格内会出现2或者4等这两个小数字,玩家只需要上下左右其中一个方向来移动出现的数字,所有的数字就会想 ...
- finally return 执行顺序问题
网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行?很多人都说不是,当然他们的回答是正确的,经过我试验,至少有两种情况下fina ...