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. 使用CopyTable工具方法在线备份HBase表

    CopyTable is a simple Apache HBase utility that, unsurprisingly, can be used for copying individual ...

  2. 算法笔记_047:复数运算(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 编程实现两个复数的运算.设有两个复数 和 ,则他们的运算公式为: 要求:(1)定义一个结构体类型来描述复数. (2)复数之间的加法.减法.乘法和除法 ...

  3. js 函数定义的2种方式

      js 函数定义的2种方式 CreateTime--2018年3月29日18:36:14 Author:Marydon 方式一: /** * 函数式声明 */ function mode() { c ...

  4. nodejs升级

    命令如下: sudo npm install n -g 然后就可以使用n命令: sudo n 0.12.2 这个命令是将nodejs升级到0.12.2版本. sudo n stable 这个命令是升级 ...

  5. ORM,ORM的原理及测试案例

      提纲 一.什么是ORM.二.反射以及Attribute在ORM中的应用.三.创建一个数据库表和表对应的实体model.四.实体model如何映射出数据库表.五.组合ORM映射生成insert语句. ...

  6. 11g RAC 加节点 之 手动加入vip 资源

    今天在给一套2节点rac 加入一个节点3时碰到几个问题: 1.原生产rac 环境私网网卡,没有使用多张冗余网卡,为保证gi 稳定性,禁用了haip: but ,埋下了一个不是坑的坑!!!!!!!!!! ...

  7. AppCompat v23.2  -- Vectors的时代

    表示速度真快啊,刚公布的23.2,就有人写blog了 原文:https://medium.com/@chrisbanes/appcompat-v23-2-age-of-the-vectors-91cb ...

  8. laravel多条件查询,及分页

    $res = DtkModel::where('ID','>','1')->select("ID")->get()->paginate(20);//不成立 ...

  9. MFS排错

    [root@Nginx_Master mfs]# /app/server/mfs/sbin/mfsmaster start working directory: /app/server/mfs/var ...

  10. 漫谈Linux下的音频问题(转)

    转自 http://www.kunli.info/2009/03/24/linux-sound-issue/ 现今的互联网,比较Linux和Windows的战争贴基本都成月经贴了.一群群激进的用户不断 ...