[SPOJ1811]Longest Common Substring 后缀自动机 最长公共子串
题目链接:http://www.spoj.com/problems/LCS/
题意如题目,求两个串的最大公共子串LCS。
首先对其中一个字符串A建立SAM,然后用另一个字符串B在上面跑。
用一个变量Lcs来记录当前答案,如果能转移到下一个状态则Lcs++。
若不能转移说明需要重新选择状态,则不断地跳到当前状态的fa状态,如果发现能够转移就停下来,Lcs变为当前状态的len+1并转移到下一个可行状态。
这里很像AC自动机的fail指针的跳跃。因为fa状态是当前状态的后缀,已经被匹配过,而fa状态有更多的机会转移。
于是最后的答案就是所有状态下Lcs的最大值。这样做的总体思想是求出对于每一个位置能向前扩展的最大长度。值得注意的是对于一个成功匹配状态s的匹配长度显然也可以作为它fa的匹配长度。因为fa的right集合一定包含了s的right集合,即都包含了当前的Lcs串的结束位置,从s开始向上更新一遍就好了,不过这里好像不需要。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
char a[],b[];
struct State{
int ch[],fa,len;
void init(){
fa=-;
len=;
memset(ch,-,sizeof(ch));
}
}T[];
int cnt=,la;
void Extend(int c){
int end=++cnt,tmp=la;
T[end].init();
T[end].len=T[tmp].len+;
while((~tmp)&&(!~T[tmp].ch[c])){
T[tmp].ch[c]=end;
tmp=T[tmp].fa;
}
if(!~tmp) T[end].fa=;
else{
int ne=T[tmp].ch[c];
if(T[tmp].len+==T[ne].len) T[end].fa=ne;
else{
int np=++cnt;
T[np]=T[ne];
T[np].len=T[tmp].len+;
T[end].fa=T[ne].fa=np;
while((~tmp)&&T[tmp].ch[c]==ne){
T[tmp].ch[c]=np;
tmp=T[tmp].fa;
}
}
}
la=end;
}
void solve(){
int ans=;
T[].init();
for(int i=;i<=n;i++) Extend(a[i]-'a');
int Lcs=,o=;
for(int i=;i<=m;i++){
int c=b[i]-'a';
if(~T[o].ch[c]){
o=T[o].ch[c];
ans=max(ans,++Lcs);
}
else{
while((~o)&&(!~T[o].ch[c])) o=T[o].fa;
if(!~o) o=Lcs=;
else{
Lcs=T[o].len+;
o=T[o].ch[c];
ans=max(ans,Lcs);
}
}
}
printf("%d\n",ans);
}
int main(){
scanf("%s%s",a+,b+);
n=strlen(a+);
m=strlen(b+);
solve();
return ;
}
[SPOJ1811]Longest Common Substring 后缀自动机 最长公共子串的更多相关文章
- SPOJ1811 LCS - Longest Common Substring(后缀自动机)
		
A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...
 - SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)
		
题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...
 - SPOJ 1811 Longest Common Substring 后缀自动机
		
模板来源:http://www.neroysq.com/?p=76 思路:http://blog.sina.com.cn/s/blog_7812e98601012dfv.html 题意就是求两个字符串 ...
 - spoj 1811 LCS - Longest Common Substring (后缀自己主动机)
		
spoj 1811 LCS - Longest Common Substring 题意: 给出两个串S, T, 求最长公共子串. 限制: |S|, |T| <= 1e5 思路: dp O(n^2 ...
 - spoj1811 Longest Common Substring
		
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
 - hdu 1403 Longest Common Substring 后缀数组 模板题
		
题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...
 - POJ 2217 (后缀数组+最长公共子串)
		
题目链接: http://poj.org/problem?id=2217 题目大意: 求两个串的最长公共子串,注意子串是连续的,而子序列可以不连续. 解题思路: 后缀数组解法是这类问题的模板解法. 对 ...
 - POJ-2774-Long Long Message(后缀数组-最长公共子串)
		
题意: 给定两个字符串 A 和 B,求最长公共子串. 分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长公共子串等价于求 A 的后缀和 B 的后缀的最长公共前缀的最大 ...
 - POJ3294 Life Forms —— 后缀数组 最长公共子串
		
题目链接:https://vjudge.net/problem/POJ-3294 Life Forms Time Limit: 5000MS Memory Limit: 65536K Total ...
 
随机推荐
- UML之实现图
			
我们前面学过的用例图.类图.活动图.顺序图和协作图都描写叙述了逻辑和设计方面的信息.那么如今我们来学习和实现有关的两个图:构件图和部署图. 实现图用来描写叙述实现方面的信息,它从系统的层次来描写叙述下 ...
 - 2016/05/11   Thinkphp 3.2.2   验证码   使用     及校验
			
先新建一个公共控制器,用于放置验证码的实例化代码(不用新建控制器也行,任意公共控制器都可以). 例如:PublicController.class.php 4 5 6 7 8 9 10 11 12 1 ...
 - HDU 4897 Little Devil I 树链剖分+线段树
			
Little Devil I Problem Description There is an old country and the king fell in love with a devil. T ...
 - java8--NIO(java疯狂讲义3复习笔记)
			
NIO采用内存映射文件的方式处理输入输出,NIO将文件或文件的一段区域映射到内存中,这样就可以像访问内存一样来访问文件了(这种方式模拟了操作系统上的虚拟内存的概念),通过这种方式来进行输入输出比传统的 ...
 - Delphi指向函数指针的指针
			
type TFunc=procedure; procedure MyFunc; begin ShowMessage('Run my func'); end; procedure TForm1.Butt ...
 - PP-生产订单状态
			
转自:http://www.cnblogs.com/mingdashu/p/5566108.html SAP系统的常见订单状态如下: · CRTD (创建):标识生产订单刚刚创建,此时禁 ...
 - 关于warning: Clock skew detected. Your build may be incomplete. 的解决方法【转】
			
本文转载自:http://blog.csdn.net/jeesenzhang/article/details/40300127 今天发现电脑的系统时间不正确,因此将时钟进行了修改,回头编译Linux ...
 - ubuntu php5.6源码安装
			
本系列的lnmp的大框架基本上是按照http://www.linuxzen.com/lnmphuan-jing-da-jian-wan-quan-shou-ce-si-lnmpda-jian-yuan ...
 - Android开发之自定义对话框
			
由于系统自带的对话框不好看,于是本人就自定义了一个对话框,以后有类似的就可以直接使用啦.先上效果图: 1,布局文件dialog_clear_normal.xml <?xml version=&q ...
 - Burnside&Polya
			
以前只是直接用了这两个式子..今天才仔细看了证明..[网上的真是难懂啊 我看的几个博客地址(各有优缺): 其实如果能懂的话 只看博客B就可以了 首先是一些置换群方面的定义和性质 博客A:http:/ ...