题目大意:

给出两个长度小于等于25W的字符串,求它们的最长公共子串。

题目链接:http://www.spoj.com/problems/LCS/

算法讨论:

二分+哈希, 后缀数组, 后缀自动机。

随意做。这里面只写一下我对后缀自动机做法的理解。

首先,我们假设两个串分别为A串和B串,我们先对建立出A串的后缀自动机,然后对于B串的每一位,我们进行如下的操作:首先从第1位开始,Parent树上的位置在root,那么对于每一次操作,如果当前结点的字符可以匹配当前B串中所考虑到的字符,那么自然就len ++,然后继续沿着Parent树向下走。如果当前失配,那么根据“在Parent树上某一个结点状态的pre指针指向的是可以接收同样后缀的状态结点”这条性质,我们在parent树上向上跳。此时,根据parent树原理,其父亲的right集合元素数目变多,字符串长度变短,那么,就可以这么考虑,刚刚在s(临时设个变量表示长度)长度的时候不能完全匹配,所以我们只有减小长度才有再次匹配成功的可能,所以要凭借Parent树来完成(因为Father的Right集合元素数多,所以字符串长度就短),我们沿着Parent树向上跳,这时会出现两种情况,第一,跳到了-1.也就是null状态,这说明B[i](假设当前正在考虑第i个子串)没有在A串中出现,所以此时把len清0,然后Parent树上位置回root,从新考虑。第二,找到了匹配位置,那么len = st[p].len + 1, p为当前在Parent树上的位置,为什么这样呢?考虑b[i]可以在p这个状态结点成功匹配,由于我们是从Parent上找到这个结点的,所以其前面的字符一定都是匹配的。举个例子,假设我们当前已经成功匹配了2个字符(不是定是B串中的前两个字符,因为是子串),现在考虑b[i],即可能成为成功匹配的第三个字符,如果在p成功匹配,那么由于在Parent树上向上跳了,因为上面提到的性质(Parent树的父亲的状态表示的子串是其儿子的最长后缀),子串长度会变短。假设变短1,所以匹配完后长度变成了2.。。。

Codes:

 #include <bits/stdc++.h>
using namespace std;
const int L = + ; struct State{
int len, fa;
int next[];
}st[L<<]; struct SuffixAutomaton{
int sz, last; void Init(){
last = ;
st[].len = ; st[].fa = -;
sz ++;
}
void Extend(int c){
int cur = sz ++;
st[cur].len = st[last].len + ;
int p; for(p = last; p != - && !st[p].next[c]; p = st[p].fa)
st[p].next[c] = cur; if(p == -) st[cur].fa = ;
else{
int q = st[p].next[c];
if(st[q].len == st[p].len + ) st[cur].fa = q;
else{
int cle = sz ++;
st[cle].len = st[p].len + ;
st[cle].fa = st[q].fa;
for(int i = ; i < ; ++ i) st[cle].next[i] = st[q].next[i];
for(; p != - && st[p].next[c] == q; p = st[p].fa)
st[p].next[c] = cle;
st[q].fa = st[cur].fa = cle;
}
}
last = cur;
}
}SAM; char str1[L], str2[L]; int main(){
scanf("%s%s", str1, str2); int len1 = strlen(str1), len2 = strlen(str2);
int ans = ; SAM.Init();
for(int i = ; i < len1; ++ i)
SAM.Extend(str1[i] - 'a'); int p = , len = ;
for(int i = ; i < len2; ++ i){
int x = str2[i] - 'a'; if(st[p].next[x]){
len ++;
p = st[p].next[x];
}
else{
while(p != - && !st[p].next[x]) p = st[p].fa;
if(p == -){
len = ; p = ;
}
else{
len = st[p].len + ; p = st[p].next[x];
}
}
ans = max(ans, len);
} printf("%d\n", ans);
return ;
}

SPOJ 1811

SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)的更多相关文章

  1. SPOJ 1811 Longest Common Substring 后缀自动机

    模板来源:http://www.neroysq.com/?p=76 思路:http://blog.sina.com.cn/s/blog_7812e98601012dfv.html 题意就是求两个字符串 ...

  2. SPOJ 1811 Longest Common Substring(求两个串的最长公共子串 || 或者n个串)

    http://www.spoj.com/problems/LCS/ 题目:求两个串的最长公共子串 参考:https://www.cnblogs.com/autoint/p/10345276.html: ...

  3. SPOJ 1811. Longest Common Substring (LCS,两个字符串的最长公共子串, 后缀自动机SAM)

    1811. Longest Common Substring Problem code: LCS A string is finite sequence of characters over a no ...

  4. hdu 1403 Longest Common Substring 后缀数组 模板题

    题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...

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

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

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

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

  7. ●SPOJ 1811 Longest Common Substring

    题链: http://poj.org/problem?id=2774 题解: 求两个字符串(S,T)的最长公共子串.对 S串建后缀自动机.接下来就用这个自动机去求出能和 S串匹配的 T的每一个前缀的最 ...

  8. SPOJ 1811 Longest Common Substring

    Description 给出两个字符串,求最长公共子串. Sol SAM. 这题随便做啊...后缀数组/Hash+二分都可以. SAM就是模板啊...直接在SAM上跑就行,没有了 \(go[w]\) ...

  9. POJ 2774 求两个串的最长公共前缀 | 后缀数组

    #include<cstdio> #include<algorithm> #include<cstring> #define N 200005 using name ...

随机推荐

  1. poj2251 三维简单BFS

    D - (热身)简单宽搜回顾 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Subm ...

  2. 关于页面刷新或者调用方法事获取不到元素信息或者出现缺少对象错误的换位思考setTimeout的使用

    这两天客户的需求不能定下来,做闲人好长时间了,不如来整理下最近碰到的一些个小麻烦. 正题: 场景一. 最近在开发的过程中使用到了百度的富客户端文本编辑器(ueditor)---这是一款功能很强大的文本 ...

  3. CMS设计-组件化

    原来CMS使用的专题类的页面是 : 事先由前端写好完整页面,再交付给运营使用,这样使用的比较灵活,可以根据市场的不同需求由前端切出不同的页面,有时候一旦需求过多,就耽误切图的时间. 现在M和H5采用组 ...

  4. Java学习笔记--Swing

    1.创建框架 AWT中Frame类用来描述顶层窗口,在Swing中,这个类的名为JFrame,它从Frame类扩展. JFrame是少数几个在Swing不用绘制在画布上的组件之一,因此,它的修饰部件( ...

  5. angular--bootstrap实例日期控件【datepicker】

    head部分: <!--Bootstrap--> <link rel="stylesheet" href="/supProdom/script/boot ...

  6. linux会话命令screen详解

    Screen会话命令 我其实是把文件下载到 /home/zhang/temp/ 里面,当我N久以后再联上服务器,想看看文件下载情况怎样,那又要 cd 老半天,这时候 screen 就是好帮手了. 顾名 ...

  7. centos 6.5 hadoop 2.3 初配置

    为了安装hadoop废了好大的劲才把esxi5.5给装好. 同时装了centos6.5,由于hadoop里面有个免密码登陆所以这里讲的就是免密码登陆. 看了大家的博客文章发现转发的一部分,写ubunt ...

  8. 极简AWR报告收集指导

    1.以oracle用户登录oracle数据库,执行如下命令登录数据库: sqlplus / as sysdba 2.运行如下命令: @?/rdbms/admin/awrrpt.sql 3.出现如下信息 ...

  9. libeXosip2(1-2) -- How-To initiate, modify or terminate calls.

    How-To initiate, modify or terminate calls. The eXtented eXosip stack eXosip2 offers a flexible API ...

  10. poj2262

                                                                                                   Goldb ...