#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define maxn 500005
#define maxl 250005
using namespace std; int n,m,ans,last,len,tot,root,son[maxn][],fa[maxn],dist[maxn];
char s1[maxl],s2[maxl];
struct Tsegment{
void prepare(){last=tot=root=;}
int newnode(int x){dist[++tot]=x;return tot;}
void add(int x){
int p=last,np=newnode(dist[p]+); last=np;
for (;p&&!son[p][x];p=fa[p]) son[p][x]=np;
if (p==) fa[np]=root;
else{
int q=son[p][x];
if (dist[p]+==dist[q]) fa[np]=q;
else{
int nq=newnode(dist[p]+);
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q],fa[q]=fa[np]=nq;
for (;p&&son[p][x]==q;p=fa[p]) son[p][x]=nq;
}
}
}
}SAM;
int main(){
scanf("%s",s1+),n=strlen(s1+);
scanf("%s",s2+),m=strlen(s2+);
SAM.prepare();
for (int i=;i<=n;i++) SAM.add(s1[i]-'a');
ans=,len=,last=root;
for (int i=;i<=m;i++){
int x=s2[i]-'a';
if (son[last][x]) len++,last=son[last][x];
else{
for (;last&&!son[last][x];) last=fa[last];
if (last==) len=,last=root;
else{
len=dist[last]+,last=son[last][x];
}
}
ans=max(ans,len);
}
printf("%d\n",ans);
return ;
}

题目链接:http://begin.lydsy.com/JudgeOnline/problem.php?id=2796

题目大意:给定两个字符串,长度<=2.5*10^5,询问这两个字符串的最长公共子串的长度,这题以前用后缀数组写过,比较基础,这次是用SAM写的,比较坑爹。

做法:最近学习了后缀自动机,讲讲我的理解:

后缀自动机可以识别一个字符串中的所有子串,写过AC自动机的同学都知道Trie树,如果按照那种方法建树的话,空间复杂度为n^2,但是我们发现有很多重复的状态,我们会发现,有很多个子串的右端点集合完全相同,那么这些字符串向后匹配的能力是相同的,故可将其缩成一个状态。

我先介绍几个性质:

1.right集合要么没有交集,要么真包含,用反证法易得。

2.对于某一个right集合中字符串,其长度有一个区间,即为【min,max】,若大于这个长度区间,|right|会减小,反之增大。

3.由于性质1,我们可以发现利用right集合能建立一棵树,满足:父亲的right集合是真包含儿子节点right集合中max最大的 ,且满足父亲的max+1=儿子的min。这三条性质在建立后缀自动机的时候有用。

如何建立后缀自动机呢?

建立过程比较麻烦,大家画个图理解理解吧,orzclj……

具体看代码。。。。。细节太多。。

这于这题的做法:

对第一个字符串建立SAM,第二个字符串在SAM上匹配即可,若失配,就跳fa,因为fa的right集合真包含于自己的right集合,这样缩短字符串长度,却能增加后续匹配的可能性,及时更新答案即可。

后缀自动机。

spoj1811 Longest Common Substring的更多相关文章

  1. [SPOJ1811]Longest Common Substring 后缀自动机 最长公共子串

    题目链接:http://www.spoj.com/problems/LCS/ 题意如题目,求两个串的最大公共子串LCS. 首先对其中一个字符串A建立SAM,然后用另一个字符串B在上面跑. 用一个变量L ...

  2. SPOJ1811 LCS - Longest Common Substring(后缀自动机)

    A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...

  3. LCS - Longest Common Substring(spoj1811) (sam(后缀自动机)+LCS)

    A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...

  4. spoj1811 LCS - Longest Common Substring

    地址:http://www.spoj.com/problems/LCS/ 题面: LCS - Longest Common Substring no tags  A string is finite ...

  5. SPOJ LCS2 - Longest Common Substring II

    LCS2 - Longest Common Substring II A string is finite sequence of characters over a non-empty finite ...

  6. LintCode Longest Common Substring

    原题链接在这里:http://www.lintcode.com/en/problem/longest-common-substring/# 题目: Given two strings, find th ...

  7. Longest Common Substring

    Given two strings, find the longest common substring. Return the length of it. Example Given A = &qu ...

  8. 【SPOJ】1812. Longest Common Substring II(后缀自动机)

    http://www.spoj.com/problems/LCS2/ 发现了我原来对sam的理解的一个坑233 本题容易看出就是将所有匹配长度记录在状态上然后取min后再对所有状态取max. 但是不要 ...

  9. hdu 1403 Longest Common Substring(最长公共子字符串)(后缀数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=1403 Longest Common Substring Time Limit: 8000/4000 MS (Ja ...

随机推荐

  1. DEDECMS之六 网站地图、RSS地图

    在用织梦CMS做网站的都知道,在它的robots.txt是屏蔽掉了data目录的,可是,不巧dedecms默认的网站地图是在data下的,为了让蜘蛛更好的爬行,有必要将dedecms生成的网站地图放在 ...

  2. Android开篇(转)

    转自:http://gityuan.com/android/ 一.简述 Android系统非常庞大.错中复杂,其底层是采用Linux作为基底,上层采用包含虚拟机的Java层以及Native层,通过系统 ...

  3. FineUI小技巧(4)关闭窗体那些事

    前言 FineUI中的Window控件常用作选择.新增或编辑内容.而关闭Window控件却有很多技巧,了解这些技巧有助于项目的快速开发. 如何关闭Window控件 第一个问题就是如何关闭Window控 ...

  4. lecture6-mini批量梯度训练及三个加速的方法

    Hinton的第6课,这一课中最后的那个rmsprop,关于它的资料,相对较少,差不多除了Hinton提出,没论文的样子,各位大大可以在这上面研究研究啊. 一.mini-批量梯度下降概述 这部分将介绍 ...

  5. xmind 使用备忘

    快捷键: shift+enter 编辑文字时回车换行 enter 快速建立同级主题(纵向) tab 快速建立子主题(横向) F4 插入注释 alt+左键+移动 拖动 shift+左键+移动 将元素脱离 ...

  6. HTML5 postMessage 跨域交换数据

    前言 之前简单讲解了利用script标签(jsonp)以及iframe标签(window.name.location.hash)来跨域交换数据,今天我们来学习一下HTML5的api,利用postMes ...

  7. Code First操作Mysql数据库

    前面博客也讲了,自己做一个网站,选用的是MVC+EF Code First+MySql+EasyUI,先说下技术选型.一.为什么选择MVC? 因为之前自己做的系统大部分是webForm,MVC的之前也 ...

  8. 你是否还在质疑EF的性能

    1. 写在前面的话 一直没有写博客的习惯,感觉太浪费时间,没有那么多精力,其实仔细一想,写博客是一种习惯,也是一种心境,同时也是对自己所掌握的知识结构的一个梳理过程,对自己知识体系的一个巩固,同时也是 ...

  9. JavaScript 10分钟入门

    JavaScript 10分钟入门 随着公司内部技术分享(JS进阶)投票的失利,先译一篇不错的JS入门博文,方便不太了解JS的童鞋快速学习和掌握这门神奇的语言. 以下为译文,原文地址:http://w ...

  10. sprintf_s的教训

    sprintf_s 是个比sprintf更安全的函数,今天在使用的过程中犯了个错误,代码的大致意思如下 void Test_sprintf_s() { ]; memset(buff, , sizeof ...