【SAM】codevs3160-最长公共子串
【题目大意】
求两个字符串的最长公共子串。
【思路】
对第一个字符串建立后缀自动机,第二个字符串去匹配。cnt记录当前最长公共子串的长度,而ret记录答案。
p代表位置指针,初始在rt位置。
对于第二个字符串的某一位s[i],如果当前有s[i]孩子,则cnt+1,继续往后移动;否则沿着pre指针返回。如果pre指针返回到0,则将p回到rt,cnt清空为0;否则如果中间有点拥有s[i]孩子,cnt=step[]+1。
为什么cnt=step[]+1?不要忘了后缀自动机的本质是维护后缀,沿着pre指针跑就是往长度更小的后缀移动,某位置代表的后缀的最长长度为step[],再加上s[i],即是step[]+1。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN=+;
int n;
char str[][MAXN];
struct SAM
{
int step[MAXN*],pre[MAXN*],next[MAXN*][];
int tot,last;
inline int newNode(int cnt)
{
step[++tot]=cnt;
pre[tot]=;
for (int i=;i<;i++) next[tot][i]=;
return tot;
} inline void extend(int x)
{
int p=last;
int np=newNode(step[p]+);
while (p && !next[p][x]) next[p][x]=np,p=pre[p];
if (!p) pre[np]=;
else
{
int q=next[p][x];
if (step[q]==step[p]+) pre[np]=q;
else
{
int nq=newNode(step[p]+);
for (int i=;i<;i++) next[nq][i]=next[q][i];
pre[nq]=pre[q];
pre[q]=pre[np]=nq;
while (p&&next[p][x]==q) next[p][x]=nq,p=pre[p];
} }
last=np;
} inline void clear()
{
int tot=;
last=newNode(tot);
} inline int Query()
{
int ret=,cnt=;
int p=;
for(int i=;str[][i];i++)
{
int index=str[][i]-'a';
if(next[p][index]) p=next[p][index],cnt++;
else
{
while (p && !next[p][index]) p=pre[p];
if(!p) p=,cnt=;
else cnt=step[p]+,p=next[p][index];
/*由于沿着pre返回得到的字符串是当前字符串的后缀,所以第一个拥有index孩子的就是最长满足的后缀,长度即为step+1*/
}
ret=max(ret,cnt);
}
return ret;
}
}suf; void init()
{
scanf("%d",&n);
scanf("%s",str[]);
int len=strlen(str[]);
suf.clear();
for (int i=;i<len;i++) suf.extend(str[][i]-'a');
scanf("%s",str[]);
} int main()
{
init();
printf("%d",suf.Query());
return ;
}
【SAM】codevs3160-最长公共子串的更多相关文章
- [codevs3160]最长公共子串解题报告|后缀自动机
给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 样例就觉得不能更眼熟啊...好像之前用后缀数组做过一次 然后发现后缀自动机真的好好写啊...(当然当时学后缀数组的时候也这么认为... 这 ...
- 【文文殿下】后缀自动机(SAM)求最长公共子串的方法
首先,在A 串上建立一个SAM,然后用B串在上面跑.具体跑的方法是: 从根节点开始,建立一个指针 p ,指着B串的开头,同步移动指针,沿着SAM的边移动,如果可以移动(即存在边)那么万事皆好,直接le ...
- codevs3160 最长公共子串
传送门:http://codevs.cn/problem/3160/ [题解] CTSC前复习模板 sa的模板..记住基数排序就够了(还有height) 还有就是sa[i]表示排名为i的后缀是啥..r ...
- BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)
题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...
- codevs 3160 最长公共子串(SAM)
3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Ou ...
- 【codevs3160】最长公共子串 后缀数组
题目描述 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入 读入两个字符串 输出 输出最长公共子串的长度 样例输入 yeshowmuchiloveyoumydearmotherrea ...
- 【spoj2774】最长公共子串
题目描述: 给你两个字符串,求它们最长公共子串的长度,如果不存在公共子串则输出0. 样例输入: yeshowmuchiloveyoumydearmotherreallyicannotbelieveit ...
- SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)
题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...
- SCOJ 4493: DNA 最长公共子串 后缀自动机
4493: DNA 题目连接: http://acm.scu.edu.cn/soj/problem.action?id=4493 Description Deoxyribonucleic acid ( ...
随机推荐
- I题 hdu 1234 开门人和关门人
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1234 开门人和关门人 Time Limit: 2000/1000 MS (Java/Others) ...
- python 实现二叉树相关算法
一.构建与遍历二叉树 基本性质 1)在二叉树的第i层上最多有2i-1 个节点 .(i>=1)2)二叉树中如果深度为k,那么最多有2k-1个节点.(k>=1)3)在完全二叉树中,具有n个节点 ...
- 【Windows使用笔记】Windows科研软件
1 Anaconda Anaconda指的是一个开源的Python发行版本,其包含了conda.Python等180多个科学包及其依赖项.主要是内置有jupyter notebook和jupyter ...
- 【Python学习】解决pandas中打印DataFrame行列显示不全的问题
在使用pandas的DataFrame打印时,如果表太长或者太宽会自动只给前后一些行列,但有时候因为一些需要,可能想看到所有的行列. 所以只需要加一下的代码就行了. #显示所有列 pd.set_opt ...
- Tornado 目录
第一章:引言 1.1 Tornado是什么? 1.1.1 Tornado入门 1.1.2 社区和支持 1.2 简单的Web服务 1.2.1 Hello Tornado 1.2.1.1 参数handle ...
- linux编程之共享内存
linux 进程间通信(IPC)包括3种机制:消息队列.信号量.共享内存.消息队列和信号量均是内核空间的系统对象,经由它们 的数据需要在内核和用户空间进行额外的数据拷贝:而共享内存和访问它的所有应用程 ...
- MinnowBoard
MinnowBoard https://github.com/RafaelRMachado/MinnowBoard https://github.com/RafaelRMachado https:// ...
- Android内存溢出解决方案总结
我的视频会议中有三个内存泄露的崆点: 1) BNLiveControlView mView = this; 未释放 (自定义view中自己引用自己造成) 2) 在自定义View中区注册了系统的网络变化 ...
- 《Java编程思想》阅读笔记二
Java编程思想 这是一个通过对<Java编程思想>(Think in java)进行阅读同时对java内容查漏补缺的系列.一些基础的知识不会被罗列出来,这里只会列出一些程序员经常会忽略或 ...
- java的关键字final
final可以修饰类,成员方法,成员变量. 1.final修饰的类不能被继承,所以没有子类 final class First{ int num; } class Second extends Fir ...