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

题意:给两个串A和B,求这两个串的最长公共子串。

分析:其实本题用后缀数组的DC3已经能很好的解决,这里我们来说说利用后缀自动机如何实现。

对于串A和B,我们先构造出串A的后缀自动机,那么然后用B串去匹配,对于B,我们一位一位地扫描,维护一个ans值,表示从

B串的开始到B[i]的这个子串与A的最长公共子串。

假设现在到B[i-1]的最长公共子串长度为ans,然后我们来看B[i],如果当前节点有B[i]这个孩子,那么直接就len++即可。

如果没有就找一直向前找pre,直到找到有B[i]这个孩子的节点。

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h> using namespace std;
const int N=250005; struct State
{
State *pre,*go[26];
int step;
void clear()
{
pre=0;
step=0;
memset(go,0,sizeof(go));
}
}*root,*last; State statePool[N*2],*cur; void init()
{
cur=statePool;
root=last=cur++;
root->clear();
} void Insert(int w)
{
State *p=last;
State *np=cur++;
np->clear();
np->step=p->step+1;
while(p&&!p->go[w])
p->go[w]=np,p=p->pre;
if(p==0)
np->pre=root;
else
{
State *q=p->go[w];
if(p->step+1==q->step)
np->pre=q;
else
{
State *nq=cur++;
nq->clear();
memcpy(nq->go,q->go,sizeof(q->go));
nq->step=p->step+1;
nq->pre=q->pre;
q->pre=nq;
np->pre=nq;
while(p&&p->go[w]==q)
p->go[w]=nq, p=p->pre;
}
}
last=np;
} char A[N],B[N]; int main()
{
int n,m;
scanf("%s%s",A,B);
n=strlen(A);
m=strlen(B);
init();
for(int i=0; i<n; i++)
Insert(A[i]-'a');
int ans=0,len=0;
State *p=root;
for(int i=0; i<m; i++)
{
int x=B[i]-'a';
if(p->go[x])
{
len++;
p=p->go[x];
}
else
{
while(p&&!p->go[x]) p=p->pre;
if(!p) p=root,len=0;
else len=p->step+1,p=p->go[x];
}
ans=max(ans,len);
}
printf("%d\n",ans);
return 0;
}

SPOJ1811最长公共子串问题(后缀自动机)的更多相关文章

  1. 【wikioi】3160 最长公共子串(后缀自动机)

    http://codevs.cn/problem/3160/ sam的裸题...(之前写了spoj上另一题sam的题目,但是spoj被卡评测现在还没评测完QAQ打算写那题题解时再来详细介绍sam的.. ...

  2. CODE【VS】3160 最长公共子串 (后缀自动机)

    3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...

  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. 【BZOJ4032】[HEOI2015]最短不公共子串(后缀自动机,序列自动机)

    [BZOJ4032][HEOI2015]最短不公共子串(后缀自动机,序列自动机) 题面 BZOJ 洛谷 题解 数据范围很小,直接暴力构建后缀自动机和序列自动机,然后直接在两个自动机上进行\(bfs\) ...

  5. BZOJ4032: [HEOI2015]最短不公共子串(后缀自动机+序列自动机)

    题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...

  6. cogs249 最长公共子串(后缀数组 二分答案

    http://cogs.pro:8080/cogs/problem/problem.php?pid=pxXNxQVqP 题意:给m个单词,让求最长公共子串的长度. 思路:先把所有单词合并成一个串(假设 ...

  7. POJ 3294 Life Forms [最长公共子串加强版 后缀数组 && 二分]

    题目:http://poj.org/problem?id=3294 Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submiss ...

  8. 【poj1226-出现或反转后出现在每个串的最长公共子串】后缀数组

    题意:求n个串的最长公共子串,子串出现在一个串中可以是它的反转串出现.总长<=10^4. 题解: 对于每个串,把反转串也连进去.二分长度,分组,判断每个组. #include<cstdio ...

  9. BZOJ4032 [HEOI2015]最短不公共子串 【后缀自动机 + 序列自动机 + dp】

    题目链接 BZOJ4032 题解 首先膜\(hb\) 空手切神题 一问\(hash\),二问枚举 三问\(trie\)树,四问\(dp\) 南二巨佬神\(hb\) 空手吊打自动机 \(orz orz ...

随机推荐

  1. 关于"cin>>"输入成功或失败时的“返回值”(转载)

    今天在看c++primer的时候,读到其中这样一段话: When we use an istream as a condition, the effect is to test the state o ...

  2. BZOJ 1407: [Noi2002]Savage( 数论 )

    枚举答案, 然后O(N^2)枚举野人去判他们是否会在有生之年存在同山洞. 具体做法就是: 设第x年相遇, 则 Ci+x*Pi=Cj+x*Pj (mod M), 然后解同余方程. 复杂度应该是O(ans ...

  3. 在ProgressBar上加文字----显示百分比的进度条

    http://www.cnblogs.com/3dant/archive/2011/04/25/2026776.html

  4. java 键盘输入多种方法 .(转载)

    一.java不像C中拥有scanf这样功能强大的函数,大多是通过定义输入输出流对象.常用的类有BufferedReader,Scanner. 实例程序: 1.利用 Scanner 实现从键盘读入int ...

  5. django学习之Model(五)MakingQuery

    接着上篇. 10-一次更新多个对象 有时想要对QuerySet中的所有对象的某一个field来设定一个值,这时候可以像下边这样用update(): # Update all the headlines ...

  6. java 文件处理

    package javax.org.path; import java.math.BigDecimal; /** * @Author:jilongliang * @Date :2013-6-18 *  ...

  7. BBM(Bad Block Management)坏块管理

    不管WL算法如何高明,在使用中都会碰到一个头痛的问题,那就是坏块,所以一个SSD必须要有坏块管理机制.何谓坏块?一个闪存块里包含有不稳定的地址,不能保证读/写/擦时数据的准确性.            ...

  8. Make Yahoo! Web Service REST Calls With C#

    原文 http://developer.yahoo.com/dotnet/howto-rest_cs.html The .NET Framework provides classes for perf ...

  9. 补丁(patch)的制作与应用

    命令简介 用到的两个命令是diff和patch. diff diff可以比较两个东西,并可同时记录下二者的区别.制作补丁时的一般用法和常见选项为: diff [选项] 源文件(夹) 目的文件(夹) - ...

  10. 如何使用ssh-keygen生成key

    ssh-keygen - 生成.管理和转换认证密钥 通常使用:[b]ssh-keygen -i -f 公密匙名>> authorized_keys[/b] 语法详细介绍 [code]ssh ...