SPOJ1811最长公共子串问题(后缀自动机)
题目: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最长公共子串问题(后缀自动机)的更多相关文章
- 【wikioi】3160 最长公共子串(后缀自动机)
http://codevs.cn/problem/3160/ sam的裸题...(之前写了spoj上另一题sam的题目,但是spoj被卡评测现在还没评测完QAQ打算写那题题解时再来详细介绍sam的.. ...
- CODE【VS】3160 最长公共子串 (后缀自动机)
3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...
- SPOJ 1811. Longest Common Substring (LCS,两个字符串的最长公共子串, 后缀自动机SAM)
1811. Longest Common Substring Problem code: LCS A string is finite sequence of characters over a no ...
- 【BZOJ4032】[HEOI2015]最短不公共子串(后缀自动机,序列自动机)
[BZOJ4032][HEOI2015]最短不公共子串(后缀自动机,序列自动机) 题面 BZOJ 洛谷 题解 数据范围很小,直接暴力构建后缀自动机和序列自动机,然后直接在两个自动机上进行\(bfs\) ...
- BZOJ4032: [HEOI2015]最短不公共子串(后缀自动机+序列自动机)
题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...
- cogs249 最长公共子串(后缀数组 二分答案
http://cogs.pro:8080/cogs/problem/problem.php?pid=pxXNxQVqP 题意:给m个单词,让求最长公共子串的长度. 思路:先把所有单词合并成一个串(假设 ...
- POJ 3294 Life Forms [最长公共子串加强版 后缀数组 && 二分]
题目:http://poj.org/problem?id=3294 Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submiss ...
- 【poj1226-出现或反转后出现在每个串的最长公共子串】后缀数组
题意:求n个串的最长公共子串,子串出现在一个串中可以是它的反转串出现.总长<=10^4. 题解: 对于每个串,把反转串也连进去.二分长度,分组,判断每个组. #include<cstdio ...
- BZOJ4032 [HEOI2015]最短不公共子串 【后缀自动机 + 序列自动机 + dp】
题目链接 BZOJ4032 题解 首先膜\(hb\) 空手切神题 一问\(hash\),二问枚举 三问\(trie\)树,四问\(dp\) 南二巨佬神\(hb\) 空手吊打自动机 \(orz orz ...
随机推荐
- Mybatis设置自增主键
useGeneratedKeys="true" keyProperty="id" 方法1: <insert id="insert" p ...
- Application(basic)----Easyui
一,效果图. 二,源代码. <!DOCTYPE html><html><head> <meta charset="UTF-8"> & ...
- linux杂记(七)linux档案与目录管理指令
1.目录的相关操作:cd,pwd,mkdir,rmdir 路径(PATH): 绝对路径:路径的写法[一定由根目录/写起],例如/usr/share/doc这个目录 相对路径:路径的写法[不是由/写起] ...
- ubuntu-10.04的测试环境 安装测试 Coreseek开源中文检索引擎-Sphinx中文版
主要参考文档:http://www.coreseek.cn/products-install/install_on_bsd_linux/ 一. 32位版本: coreseek安装需要预装的软件: ap ...
- python 推导式和迭代器、生成器
1.常用推导式 推导式是从一个或者多个迭代器快速简洁创建数据结构的一种方法. 1.1 _ 列表推导式 最简单的形式: [exprssion for item in iterable] 示例: nu ...
- querySelectorAll 和 jQuery选择器
参考 http://xahlee.info/js/jquery_diff_querySelectorAll.html http://stackoverflow.com/questions/115035 ...
- MYSQL 退出的三个方式
方式1: exit 方式2: quit 方式3: \q
- 《windows程序设计》学习_2.1:初识消息
#include <windows.h> //#define WM_MYMSG (WM_USER +100) LRESULT CALLBACK WndProc(HWND,UINT,WPAR ...
- Juicy Couture_百度百科
Juicy Couture_百度百科 Juicy Couture
- Oracle触发器(trigger):view,schema,database
视图trigger, instead of 我们知道如果一个view只是由一个table构成,那在view上做啥操作没太多限制.如果view是由多个table组成那在view上做啥unpdate,in ...