题目链接 POJ2774

SPOJ1811 LCS - Longest Common Substring

确实比后缀数组快多了(废话→_→)。

\(Description\)

求两个字符串最长公共子串

\(Solution\)

对串A建立后缀自动机。

A的SAM中包含A的所有子串,且根到每个节点的路径都是A的子串。如果B(的一部分?)匹配到了SAM上的某个节点,那么这便是AB的公共子串。求出这些点的max(len)即可。

用串B在SAM上逐位匹配,如果匹配,就继续沿着匹配边走;

否则,为了匹配当前这位,丢掉B前面一部分,因为fa[p]节点代表的后缀是p所代表后缀的上一个可接受后缀,所以跳fa[p],直到可匹配当前位或到根节点。

注意now的更新方式,如果匹配则+1,否则跳完p后,在p=son[p][c]前用len[p]+1更新now。因为此时p完全匹配了,而len[son[p][c]]是son[p][c]所代表的串的max(len)。(大概是这样吧。。)

感觉这东西好玄学啊。。

//15064K	79MS
//SPOJ:69M 0.04s
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=250005<<1;//2n char s[N>>1];
struct Suffix_Automaton
{
int las,tot,son[N][26],fa[N],len[N];
void Insert(int c)
{
int p=las,np=++tot; len[las=np]=len[p]+1;
for(; p&&!son[p][c]; p=fa[p]) son[p][c]=np;
if(!p) fa[np]=1;
else
{
int q=son[p][c];
if(len[q]==len[p]+1) fa[np]=q;
else
{
int nq=++tot; len[nq]=len[p]+1;
memcpy(son[nq],son[q],sizeof son[q]);
fa[nq]=fa[q], fa[q]=fa[np]=nq;
for(; son[p][c]==q; p=fa[p]) son[p][c]=nq;
}
}
}
void Build(char *s)
{
las=tot=1;
for(int i=0,l=strlen(s); i<l; ++i) Insert(s[i]-'a');
}
void Query(char *s)
{
int ans=0;
for(int c,now=0,p=1,i=0,l=strlen(s); i<l; ++i,ans=std::max(ans,now))
if(son[p][c=s[i]-'a']) p=son[p][c], ++now;
else
{
for(; p&&!son[p][c]; p=fa[p]);
if(!p) p=1, now=0;
else now=len[p]+1, p=son[p][c];
// WA: else p=son[p][c], now=len[p];
}
printf("%d",ans);
}
}sam; int main()
{
scanf("%s",s), sam.Build(s);
scanf("%s",s), sam.Query(s);
return 0;
}

一些有关后缀自动机的东西:

论文。。

构造:

后缀自动机详解(感觉这写的理论好理解)

后缀自动机学习小结(从维护right来写?)

后缀自动机学习总结(从简化状态来写?)

后缀自动机构造过程演示(这个过程演示很好啊)

后缀自动机的构造(没看)

题目:

后缀自动机的性质应用

后缀自动机总结

后缀自动机学习小结(应用理论)

几张SAM的例图:

aabbab



aabb


POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀自动机)的更多相关文章

  1. POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀数组 倍增)

    题目链接 POJ2774 SPOJ1811 LCS - Longest Common Substring 比后缀自动机慢好多(废话→_→). \(Description\) 求两个字符串最长公共子串 ...

  2. SPOJ 1811 LCS [后缀自动机]

    题意: 求两个串的最大连续子串 一个串建SAM,另一个串在上面跑 注意如果走了Suffix Link,sum需要更新为t[u].val+1 Suffix Link有点像失配吧,当前状态s走不了了就到S ...

  3. spoj 1811 LCS - Longest Common Substring (后缀自己主动机)

    spoj 1811 LCS - Longest Common Substring 题意: 给出两个串S, T, 求最长公共子串. 限制: |S|, |T| <= 1e5 思路: dp O(n^2 ...

  4. spoj 1812 lcsII (后缀自动机)

    spoj 1812 lcsII (后缀自动机) 题意:求多个串的lcs,最多10个串,每个串最长10w 解题思路:后缀自动机.先建好第一个串的sam,然后后面的串拿上去跑(这个过程同前一题).sam上 ...

  5. [POJ 2774] Long Long Message 【后缀数组】

    题目链接:POJ - 2774 题目分析 题目要求求出两个字符串的最长公共子串,使用后缀数组求解会十分容易. 将两个字符串用特殊字符隔开再连接到一起,求出后缀数组. 可以看出,最长公共子串就是两个字符 ...

  6. POJ 2774 Long Long Message [ 最长公共子串 后缀数组]

    题目:http://poj.org/problem?id=2774 Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total ...

  7. ●POJ 2774 Long Long Message

    题链: http://poj.org/problem?id=2774题解: 后缀自动机 使用后缀自动机匹配,思路如下: 即如果当前的x字符匹配失败了,就可以从当前已经匹配的串的后缀去继续匹配. 然后不 ...

  8. SPOJ - LCS 后缀自动机入门

    LCS - Longest Common Substring A string is finite sequence of characters over a non-empty finite set ...

  9. Longest Common Substring II SPOJ - LCS2 (后缀自动机)

    Longest Common Substring II \[ Time Limit: 236ms\quad Memory Limit: 1572864 kB \] 题意 给出\(n\)个子串,要求这\ ...

随机推荐

  1. Codeforces 543 B. World Tour

    http://codeforces.com/problemset/problem/543/B 题意: 给定一张边权均为1的无向图. 问至多可以删除多少边,使得s1到t1的最短路不超过l1,s2到t2的 ...

  2. Codeforces Round #547 (Div. 3) D

    http://codeforces.com/contest/1141/problem/D 题目大意: 鞋子匹配,用一个小写字母表示一种颜色.L[i]表示左脚的颜色,R[i]表示右脚的颜色,只有当L[i ...

  3. HDU 5528 反演

    $f(m)=\sum\limits_{i=1}^{m-1}\sum\limits_{j=1}^{m-1}[(ij,m) \ne m]$,$g(n)=\sum\limits_{m|n}f(m)$,$1 ...

  4. FFmpeg编码扩展之————编码库的扩展(libfdk-aac)

    ffmpeg windows版没有libfdk-acc 请求该地址下载:http://tmod.nmm-hd.org/FFmpeg/

  5. <dl>

    定义列表 自定义列表不仅仅是一列项目,而是项目及其注释的组合. 自定义列表以 <dl> 标签开始.每个自定义列表项以 <dt> 开始.每个自定义列表项的定义以 <dd&g ...

  6. Sortable.js

    拖拽的时候主要由这几个事件完成, ondragstart 事件:当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元素上 ondragenter 事件:当拖曳元素进入目标元素的时候触发的事件,此 ...

  7. cmd命令,bat脚本

    1.cd /d D:\>cd mysql D:\mysql>cd /d C:/TEMP C:\Temp>cd /? 显示当前目录名或改变当前目录. CHDIR [/D] [drive ...

  8. Linux sleep命令

    Linux sleep命令可以用来将目前动作延迟一段时间. 使用权限:所有使用者. 语法 sleep [--help] [--version] number[smhd] 参数说明: --help : ...

  9. shell脚本练习【转】

    1.写一个脚本,判断当前系统上所有用户的shell是否为可登录shell(即用户的shell不是/sbin/nologin):分别这两类用户的个数:通过字符串比较来实现: #脚本内容 [root@ce ...

  10. 【mac】7z 终端命令行

    链接:http://www.2cto.com/os/201410/341079.html 7z指令 7z是7zip压缩工具的常用压缩文件格式.7zip是一个开源的压缩工具,软件本身十分小巧,功能强大, ...