spoj1811 Longest Common Substring
#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的更多相关文章
- [SPOJ1811]Longest Common Substring 后缀自动机 最长公共子串
题目链接:http://www.spoj.com/problems/LCS/ 题意如题目,求两个串的最大公共子串LCS. 首先对其中一个字符串A建立SAM,然后用另一个字符串B在上面跑. 用一个变量L ...
- SPOJ1811 LCS - Longest Common Substring(后缀自动机)
A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...
- LCS - Longest Common Substring(spoj1811) (sam(后缀自动机)+LCS)
A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...
- spoj1811 LCS - Longest Common Substring
地址:http://www.spoj.com/problems/LCS/ 题面: LCS - Longest Common Substring no tags A string is finite ...
- SPOJ LCS2 - Longest Common Substring II
LCS2 - Longest Common Substring II A string is finite sequence of characters over a non-empty finite ...
- LintCode Longest Common Substring
原题链接在这里:http://www.lintcode.com/en/problem/longest-common-substring/# 题目: Given two strings, find th ...
- Longest Common Substring
Given two strings, find the longest common substring. Return the length of it. Example Given A = &qu ...
- 【SPOJ】1812. Longest Common Substring II(后缀自动机)
http://www.spoj.com/problems/LCS2/ 发现了我原来对sam的理解的一个坑233 本题容易看出就是将所有匹配长度记录在状态上然后取min后再对所有状态取max. 但是不要 ...
- hdu 1403 Longest Common Substring(最长公共子字符串)(后缀数组)
http://acm.hdu.edu.cn/showproblem.php?pid=1403 Longest Common Substring Time Limit: 8000/4000 MS (Ja ...
随机推荐
- repeater 根据输入 返回汉字
page repeater <asp:Repeater ID="r_scoreCount" runat="server"> <HeaderTe ...
- .net混淆、反编译工具调查
常用的工具列表[比较常见的] 混淆器.加密 Dotfuscator VS默认带的工具,不过是个社区版 强度不大 dotNET Reactor 使用了NativeCode 和混淆的形式 Xenocode ...
- Alpha版本发布说明
软件发布的同时,在团队博客上写一个发布说明 ▪ 列出这一版本的新功能 ▪ 这一版本修复的缺陷 ▪ 对运行环境的要求 ▪ 安装方法 ▪ 描述系统已知的问题和限制 ...
- sqlserver数据库附加分离备份还原命令
--获取所有数据库的名称 select [name] from master.dbo.sysdatabases where [name]='master' --判断数据库是否存在 if exists( ...
- DOM 元素节点几何量与滚动几何量
当在 Web 浏览器中查看 HTML 文档时,DOM 节点被解析,并被渲染成盒模型(如下图),有时我们需要知道一些信息,比如盒模型的大小,盒模型在浏览器中的位置等等,本文我们就来详细了解下元素节点的几 ...
- 初用protobuf-csharp-port
下面这个用法是参照protobuf-csharp-port的官方wiki,参见: https://code.google.com/p/protobuf-csharp-port/wiki/Getting ...
- Hotspot内存溢出测试
一.堆溢出 在执行代码时通过设置堆的最小值-Mms以及堆的最大值-Mmx来控制堆的大小,-XX参数dump出堆内存快照以便对内存溢出进行分析.通过创建大量对象来使堆溢出,当堆内存溢出时会提示OutOf ...
- eclipse的历史版本及下载
有时候我们总会遇到在需要eclipse而无法及时找到的时候, 所以那些有用的链接, 是帮助我们能够及时找到我们想要版本的额最好方式 Eclipse 3.1 IO[木卫一,伊奥] 2005 http:/ ...
- kill 根据PID终止进程
根据PID终止进程 kill [option] PID-list kill 通过向一个或多个进程发送信号来终止进程.除超级用户外,只有进程的所有者才可以对进程执行kill 参数 PID-list为ki ...
- C#分割字符串
命名空间:System.String.Split 程序集:mscorlib( mscorlib.dll) 简单实例: string before = "12,50,30"; str ...