http://codevs.cn/problem/3160/

sam的裸题。。。(之前写了spoj上另一题sam的题目,但是spoj被卡评测现在还没评测完QAQ打算写那题题解时再来详细介绍sam的。。。。那就再等等吧。

求两个串的lcs话,就是先建立a串的sam,然后用b的字串去匹配a中。

因为sam中的转移可以直接对应所有后缀的开头,因此匹配的时候是可以直接找到这个后缀开头,然后继续转移,直至找到整个串。而因为sam中的parent指针就如ac自动机中的fail指针差不多,唯一的区别是sam的parent指针转移到的节点是自己的后缀(就是S到当前节点就是一个原串的前缀,而上面说的就是这个前缀的后缀,而且长度每次都递减,因此能找到最大匹配)

所以不断找然后更新即可。

如果还不懂详看clj论文

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } struct sam {
static const int N=200005;
int c[N][26], l[N], f[N], root, last, cnt;
sam() { cnt=0; root=last=++cnt; }
void add(int x) {
int now=last, a=++cnt; last=a;
l[a]=l[now]+1;
for(; now && !c[now][x]; now=f[now]) c[now][x]=a;
if(!now) { f[a]=root; return; }
int q=c[now][x];
if(l[q]==l[now]+1) { f[a]=q; return; }
int b=++cnt;
memcpy(c[b], c[q], sizeof c[q]);
l[b]=l[now]+1;
f[b]=f[q];
f[q]=f[a]=b;
for(; now && c[now][x]==q; now=f[now]) c[now][x]=b;
}
void build(char *s) {
int len=strlen(s);
rep(i, len) add(s[i]-'a');
}
int find(char *s) {
int ret=0, len=strlen(s), now=1, t=0;
rep(i, len) {
int x=s[i]-'a';
if(c[now][x]) now=c[now][x], ++t;
else {
while(now && !c[now][x]) now=f[now];
if(!now) now=root, t=0;
else t=l[now]+1, now=c[now][x];
}
ret=max(ret, t);
}
return ret;
}
}a;
const int N=100005;
char s[N];
int main() {
scanf("%s", s);
a.build(s);
scanf("%s", s);
printf("%d\n", a.find(s));
return 0;
}

  


题目描述 Description

给出两个由小写字母组成的字符串,求它们的最长公共子串的长度。

输入描述 Input Description

读入两个字符串

输出描述 Output Description

输出最长公共子串的长度

样例输入 Sample Input
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit
yeaphowmuchiloveyoumydearmother
样例输出 Sample Output

27

数据范围及提示 Data Size & Hint

单个字符串的长度不超过100000

【wikioi】3160 最长公共子串(后缀自动机)的更多相关文章

  1. codevs 3160 最长公共子串 后缀自动机

    http://codevs.cn/problem/3160/ 后缀自动机板子题,匹配的时候要注意如果到一个点失配向前匹配到一个点时,此时的tmp(当前匹配值)为t[j].len+1而不是t[t[j]. ...

  2. CODE【VS】 3160 最长公共子串 (后缀数组)

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

  3. Codevs 3160 最长公共子串(后缀数组)

    3160 最长公共子串 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长 ...

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

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

  5. CODE【VS】3160 最长公共子串 (后缀自动机)

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

  6. codevs 3160 最长公共子串

    3160 最长公共子串 http://codevs.cn/problem/3160/  时间限制: 2 s  空间限制: 128000 KB   题目描述 Description 给出两个由小写字母组 ...

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

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

  8. poj 2774 最长公共子串 后缀数组

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 25752   Accepted: 10 ...

  9. bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp)

    bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp) bzoj Luogu 题解时间 给两个小写字母串 $ A $ , $ B $ ,请你计算: ...

随机推荐

  1. uva:10487 - Closest Sums(二分查找)

    题目:10487 - Closest Sums 题目大意:给出一组数据,再给出m个查询的数字. 要求找到这组数据里的两个数据相加的和最靠近这个查询的数据,输出那两个数据的和. 解题思路:二分查找.这样 ...

  2. JDBC-DAO经典模式 实现对数据库的增、删、改、查

    JDBC(Java Data Base Connection)的作用是连接数据库 先看下jdbc连接SQLServer数据库的简单例子 代码实现(FirstJDBC): package com.jdb ...

  3. ng-class

    在前面Angularjs开发一些经验总结中我们说到在angular开发中angular controller never 包含DOM元素(html/css),在controller需要一个简单的POJ ...

  4. CSS命名规范 BEM

    良好的代码结构,HTML和css元素之间的关系,对于项目交付是很重要的! BEM解释: (1).block 是BEM的区块(B),包含内容和风格.如bootstrap框架的.container. (2 ...

  5. HBase建立二级索引的一些解决方式

    HBase的一级索引就是rowkey,我们仅仅能通过rowkey进行检索. 假设我们相对hbase里面列族的列列进行一些组合查询.就须要採用HBase的二级索引方案来进行多条件的查询. 常见的二级索引 ...

  6. [Done]FindBugs: boxing/unboxing to parse a primitive

    在开发过程中遇到了以下问题: FindBugs: boxing/unboxing to parse a primitive 查看代码(左边是老代码,右边是新的): 问题出在 自动装箱和拆箱的检查. 参 ...

  7. Android 5.0最应该实现的8个期望

    毫无疑问,Android 5 将是令人兴奋的操作系统,因为 Android4.0 至 4.4 版本之间并没有显著的差异,显然谷歌会在 5.0 版本中进行一些较大幅度的革新.那么,代号为“柠檬芝士蛋糕” ...

  8. SQL 横转竖 、竖专横 (转载) 使用Dapper.Contrib 开发.net core程序,兼容多种数据库 C# 读取PDF多级书签 Json.net日期格式化设置 ASPNET 下载共享文件 ASPNET 文件批量下载 递归,循环,尾递归 利用IDisposable接口构建包含非托管资源对象 《.NET 进阶指南》读书笔记2------定义不可改变类型

    SQL 横转竖 .竖专横 (转载)   普通行列转换 问题:假设有张学生成绩表(tb)如下: 姓名 课程 分数 张三 语文 74 张三 数学 83 张三 物理 93 李四 语文 74 李四 数学 84 ...

  9. POJ3187 Backward Digit Sums 【暴搜】

    Backward Digit Sums Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4487   Accepted: 25 ...

  10. docker容器跑tomcat遇到的坑

    使用docker容器跑tomcat,由于同一个宿主机上跑了多个容器,再加上宿主机本身跑了很多进程,导致系统总的进程数达到了8000+,而容器中tomcat的启动脚本中会调用自带的setenv.sh,在 ...