【题目大意】

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

【思路】

对第一个字符串建立后缀自动机,第二个字符串去匹配。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-最长公共子串的更多相关文章

  1. [codevs3160]最长公共子串解题报告|后缀自动机

    给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 样例就觉得不能更眼熟啊...好像之前用后缀数组做过一次 然后发现后缀自动机真的好好写啊...(当然当时学后缀数组的时候也这么认为... 这 ...

  2. 【文文殿下】后缀自动机(SAM)求最长公共子串的方法

    首先,在A 串上建立一个SAM,然后用B串在上面跑.具体跑的方法是: 从根节点开始,建立一个指针 p ,指着B串的开头,同步移动指针,沿着SAM的边移动,如果可以移动(即存在边)那么万事皆好,直接le ...

  3. codevs3160 最长公共子串

    传送门:http://codevs.cn/problem/3160/ [题解] CTSC前复习模板 sa的模板..记住基数排序就够了(还有height) 还有就是sa[i]表示排名为i的后缀是啥..r ...

  4. BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)

    题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...

  5. codevs 3160 最长公共子串(SAM)

    3160 最长公共子串   题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Ou ...

  6. 【codevs3160】最长公共子串 后缀数组

    题目描述 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入 读入两个字符串 输出 输出最长公共子串的长度 样例输入 yeshowmuchiloveyoumydearmotherrea ...

  7. 【spoj2774】最长公共子串

    题目描述: 给你两个字符串,求它们最长公共子串的长度,如果不存在公共子串则输出0. 样例输入: yeshowmuchiloveyoumydearmotherreallyicannotbelieveit ...

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

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

  9. SCOJ 4493: DNA 最长公共子串 后缀自动机

    4493: DNA 题目连接: http://acm.scu.edu.cn/soj/problem.action?id=4493 Description Deoxyribonucleic acid ( ...

随机推荐

  1. BigDecimal的用法详解

    BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组成.如果为零或正数,则标度是小数点后的位数.如果为负数,则将该数的非标度值乘以 10 的负scale 次幂. f ...

  2. 设计模式之Factory

    设计模式总共有23种模式这仅仅是为了一个目的:解耦+解耦+解耦...(高内聚低耦合满足开闭原则) 介绍: Factory Pattern有3种当然是全部是creational pattern. 1.S ...

  3. MFC不同工程(解决方案)之间对话框资源的复制与重用方法(转)

    原文转自 https://blog.csdn.net/lihui126/article/details/45556687

  4. 64_k1

    KoboDeluxe-0.5.1-22.fc26.x86_64.rpm 13-Feb-2017 22:11 1626454 k3b-17.04.1-1.fc26.x86_64.rpm 25-May-2 ...

  5. OpenRCT2-ext

    https://github.com/RollingStar/RCT-Music-Patch https://github.com/seanfisk/rct2-game-objects https:/ ...

  6. redis可编译

    redis-3.0.7 可编译 redis-3.0.7.tar.gz twemproxy-master.zip keepalived-1.2.19.tar.gz openssl-1.0.1s.tar. ...

  7. mac cocoapod安装过程

    cocoapod: 自动化管理第三方开发包的一个插件, 废话不多说, 一个新手只需做如下几个步骤 1-> 安装ruby环境(可忽略, 不是必要) 1.1 首先我们先看看当前你机器上ruby的版本 ...

  8. 苹果电脑Mac OS系统重装图文详解

    苹果电脑Mac OS系统重装图文详解 本文来自于[系统之家] www.xp85.com现在电脑都很强大,可是也很脆弱,常常需要你去维护,甚至经常需要你重装系统,那么Mac OS又如何重装系统呢?刚刚使 ...

  9. 12-7 NSDictionary

    原文:http://rypress.com/tutorials/objective-c/data-types/nsdictionary NSDictionary 如同NSSet,NSDictionar ...

  10. 18:django 日志系统

    django使用python内建的logging模块去建造自己的系统日志的,如果你想详细了解这个模块的话,请自己去看python的说明文档,这里仅仅介绍django中的日志系统 日志配置包括四个部分: ...