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 ...
随机推荐
- 【点滴积累,厚积薄发】windows schedule task中.exe程序的路径问题等问题总结
1.在发布ReportMgmt的Job时遇到一个路径问题,代码如下: doc.Load(@"Configuration\Business\business.config"); ...
- ZH奶酪:Java调用NLPIR汉语分词系统
NLPIR工具 支持自定义词表: 可以离线使用: 下载地址:http://ictclas.nlpir.org/newsdownloads?DocId=389 在线演示:http://ictclas.n ...
- opencv6.1-imgproc图像处理模块之平滑与形态学操作
这个部分是<opencv-tutorials.pdf>的部分,这部分也是几大部分中例子最多的,其实这个教程的例子都很不错,不过有些看得出来还是c接口的例子,说明例子有些年头了,其实在&qu ...
- 支付宝Cookie高危漏洞引发的思考
背景:当时我在做公司的网站支付接入,在调试支付宝WAP支付时,发现一些匪夷所思的事情: 1.我想要切换账号时退到需要输入登录信息时,原账号并没有退出,我按一下后退键又回来了: 2.我关闭浏览器也没有退 ...
- 对《重建中国.NET生态系统》评论贴的总结
Neuzilla官方微信公众号:搜 架构师联盟 或 neuzilla,也可以扫下面二维码 在看了<重建中国.NET生态系统>的各种哭爹喊娘骂街的评论之后,我觉得哦,淫才确实很多,但是么真正 ...
- [BZOJ2152]聪聪可可(点分治)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2152 分析:裸的点分治,对于每课树,记录t[0],t[1],t[2]表示到当前根节点距 ...
- 如何设置div高度为100%
div高度通常都是固定值,直接将div高度设为100%是无效的,那么如何设置才能有效呢? 直接给div设置height:100%即可,无效的原因一定是父元素的高度为0,最常见的就是给body的直接元素 ...
- 【转】Java 8十个lambda表达式案例
1. 实现Runnable线程案例 使用() -> {} 替代匿名类: //Before Java 8: new Thread(new Runnable() { @Override public ...
- python2.7到python3代码转换脚本2to3的一些介绍
你的位置: Home ‣ Dive Into Python 3 ‣ 难度等级: ♦♦♦♦♦ 使用2to3将代码移植到Python 3 ❝ Life is pleasant. Death is ...
- JS日历制作获取时间
1.直接获取 var myDate = new Date(); myDate.getYear(); 获取当前年份(2位) myDate.getFullYear(); 获取完整的年份(4位,1970-? ...