基础性质概念

  • 后缀自动机:S的SAM是个DAG,每个节点叫状态,每条带字符ch边表示+ch转移,从开始节点往下,任何一条路径都会对应一个S的子串。

不过为什么要叫"后缀"自动机呢?

  • endpos集合:endpos(s)={s的所有右端点}[s为S的一个子串]
  • 状态(节点):把endpos{}相同的等价类归为一个状态。
  • 边(ch[u][x]):上面定义也说过,状态u中每个s+x集合构成的状态。
  • 推论1:一个等价类中的两个s满足后缀关系。如果不满足,那么存在endpos{}不同。
  • 推论2:由推论1易得等价类中所有s都互相满足前后缀关系而且它们的长度是连续的[l..l+1..r]。假如不连续,存在x,y,z(x是y,z的后缀,y是z的后缀),(endpos简称)ep{x}=ep{z}!=ep{y}所以ep{x}包含ep{y},ep{y}包含ep{z},因此ed{x}=ed{y}=ed{z},与假设矛盾。
  • len[]:表示状态中s最长长度,最短的可以用接下来的变量计算。
  • 推论3:两个等价类的集合要么包含,要么不交,取决与是否有前后缀关系。如果有前后缀关系,len大的那个可以看作len小的那个加一堆前缀很好解释len小包含len大。然后没有后缀关系显然不能有交。

    推论2,3也让我们从后缀角度看待状态。

或许你认为以上就能构成后缀自动机。按照定义来说是的,但是不够。我们还要保证它的状态数和构建操作数为\(O(n)\)

接下来我们会在SAM上连一些虚边,这些虚边会构成有用的fail树

  • par[]:严格包含其ep的最小ep状态点,即par[u]包含的s'是u中s的后缀(而且连续),mnlen[par[u]]=len[u]+1
  • Fail树:father[]为par的一棵树

感性来理解就像某前缀的后缀被分成了很多状态连成一条链。

构建

叫什么增量法,就是在线字符一个一个地加。然后找其最大后缀(par[])。

前提(当前加入第i个,字符为x,这个前缀i的节点为np)

ps.可结合代码理解

首先last为前缀i-1所在的节点。p=last往fail树祖先上跳,同时更新ch[p][x],直到找到一个点ch[p][x]!=0,此时前缀i的最长后缀的长度就是len[p]+1。(因为(在p下面)比len[p]长的后面都没有x)

当然没有这么简单,我们要分三类讨论:

1.没有找到par[],par[np]=rt直接结束

令q=ch[p][x]

2.len[q]=len[p]+1直接par[np]=q

3.len[q]>len[p]+1所代表后缀字符集可以分成两类。长度<=len[p]+1的一类(可以作i前缀(np)的后缀),>len[p]+1的一类跟这次加入无关。

所以容易想到把q拆成两个点,其实拆出1个新点nq(第1类),原来的q(第2类),首先不修改q,用q原来的信息更新nq(par[],ch[][]),len[nq]=len[p]+1,然后更新par[q]=par[p]=nq(Fail树中把q,np连在nq下)。

最后容易遗忘的是p及其上面一些点(因为len[nq]=len[p]+1)原来ch[p][x]=q现在改为ch[p][x]=nq了。

复杂度

可以看看别人的博客

不会证耶?有会证的而且证的很简单的私信我?

code

点击查看代码
struct SAM {
int ch[N][27],t[N],len[N],lst,num,par[N],sz[N];
SAM() {lst=num=1;}
int Insert(int x) {
int p=lst,np=++num;lst=np;len[np]=len[p]+1;sz[np]=1;
for(;!ch[p][x];p=par[p]) ch[p][x]=np;
if(!p) {par[np]=1;return np;}
int q=ch[p][x];
if(len[q]==len[p]+1) {par[np]=q;return np;}
int nq=++num;par[nq]=par[q];len[nq]=len[p]+1;
for(int j=0;j<26;j++)ch[nq][j]=ch[q][j];
par[q]=par[np]=nq;
for(;ch[p][x]==q;p=par[p])ch[p][x]=nq;
return np;
}
}A;

用途(例题)

匹配字符串:

不用说了所有自动机(dfn)都能做的事情

多少个本质不同的字符串(位置不同串相同算同一个)

\(ans= \sum len[u]-len[fa[u]]\)每个(本质不同)字符串都唯一对应与SAM中的节点,而SAM中不同节点表示的字符集没有交集。因此就是每个节点u表示的字符个数(len[par[u]]-len[u])的和。

每个字符串出现了几次

Fail树上,每个节点\(sz[par[u]]+=sz[u]\),每个前缀对应节点(\(sz[np]=1\))

其实sz[u]就是ep等价类u中字符串对应的出现次数了

证明?

把前缀np,sz[np]=1,实际上它会给所有它的后缀+1,然后每个节点对应等价类的ep{r1,r2,r3..rk},显然sz=k。其中每个都会被前缀r1,前缀r2..前缀rk+1各+1。所以刚好+k次,得证。

SAM[详细~bushi]的更多相关文章

  1. sam格式详细说明

    原文链接 https://www.jianshu.com/p/386f520e5de1 The SAM Format Specification(sam格式说明) 1 The SAM Format S ...

  2. [转]后缀自动机(SAM)

    原文地址:http://blog.sina.com.cn/s/blog_8fcd775901019mi4.html 感觉自己看这个终于觉得能看懂了!也能感受到后缀自动机究竟是一种怎样进行的数据结构了. ...

  3. Linux中find、grep命令详细用法

    在linux下面工作,有些命令能够大大提高效率.本文就向大家介绍find.grep命令,他哥俩可以算是必会的linux命令,我几乎每天都要用到他们.本文结构如下: find命令 find命令的一般形式 ...

  4. 初创互联网公司简明创业指南 - YC新掌门Sam Altman

    本文只是一个创业指南的简明版 - 更详细的版本请查看:http://startupclass.samaltman.com 创业之前,你更应该去拥有一个好的创意,而不是一个公司.如果开始前你拥有一个好的 ...

  5. SAMTOOLS使用 SAM BAM文件处理

    [怪毛匠子 整理] samtools学习及使用范例,以及官方文档详解 #第一步:把sam文件转换成bam文件,我们得到map.bam文件 system"samtools view -bS m ...

  6. Luogu P3181 [HAOI2016]找相同字符 广义$SAM$

    题目链接 \(Click\) \(Here\) 设一个串\(s\)在\(A\)中出现\(cnt[s][1]\)次,在\(B\)中出现\(cnt[s][2]\)次,我们要求的就是: \[\sum cnt ...

  7. SAM文件格式

    帮朋友处理sam各式文件,又记不住sam各式每列代表的什么内容,干脆转个帖子留着以后查询. 在SAM输出的结果中每一行都包括十二项通过Tab分隔,从左到右分别是: 1 序列的名字 2 概括出一个合适的 ...

  8. 后缀自动机(SAM)速成手册!

    正好写这个博客和我的某个别的需求重合了...我就来讲一讲SAM啦qwq 后缀自动机,也就是SAM,是一种极其有用的处理字符串的数据结构,可以用于处理几乎任何有关于子串的问题,但以学起来异常困难著称(在 ...

  9. 【H3C交换机】cpu各个进程的详细说明

    display cpu-usage命令用来查看设备CPU占用率的统计信息,以及各个进程的cpu占用率. 各个进程详细说明如下,不同软件版本.盒式和框式的cpu进程略有不同,详细信息可以查看手册中的命令 ...

随机推荐

  1. 何使用派生类指针指向基类,即downcast向下转型?

    基类指针指向派生类,我们已经很熟了.假如我们想用派生类反过来指向基类,就需要有两个要求:1)马克-to-win:基类指针开始时指向派生类,2)我们还需要清清楚楚的转型一下. if you want t ...

  2. Android Studio安装及问题

    安装教程+虚拟机调试:https://blog.csdn.net/y74364/article/details/96121530 gradle下载缓慢解决办法:https://blog.csdn.ne ...

  3. Vue脚手架结构及vue-router路由配置

    首先官网介绍,用 Vue.js + vue-router 创建单页应用,是非常简单的.使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 vue-router 添加进来,我们需要做 ...

  4. [ SOS ] 版本控制工具 笔记

    https://www.cnblogs.com/yeungchie/ soscmd 创建工作区 soscmd newworkarea $serverName $projectName [$path] ...

  5. WIN DLL劫持提权

    WIN DLL劫持提权 原理: Windows程序启动的时候需要DLL.如果这些DLL 不存在,则可以通过在应用程序要查找的位置放置恶意DLL来提权.通常,Windows应用程序有其预定义好的搜索DL ...

  6. 使用nmtui命令解决network-scripts目录下无网卡对应配置文件问题

    //网卡通过命令ifconfig可以识别到,但是在配置文件目录下,没有该文件,一旦重启等配置了该地址的应用则可能会出现问题所以需要重新生成对应配置文件,我首先想到的就是用 nmtui 这个程序来重新生 ...

  7. pip:带你认识一个 Python 开发工作流程中的重要工具

    摘要:许多Python项目使用pip包管理器来管理它们的依赖项.它包含在Python安装程序中,是Python中依赖项管理的重要工具. 本文分享自华为云社区<使用Python的pip管理项目的依 ...

  8. 今天记录一下h5跳转小程序,可以通过短信推广小程序

    今天记录一下h5跳转小程序最简单的方法,首先准备条件,是一个已经上线的小程序 根据URL Schame进行跳转,在微信公众平台登录自己的小程序,然后生成RL Schame,如下图 其次按照步骤进行小程 ...

  9. TCP/IP 协议标准简单描述

    TCP/IP 协议标准简单描述 说明 分为三部分:中文名称.缩写.说明. 应用层 DNS 域名服务 (DNS) 功能: 将域名转化为IP地址 BOOTP 引导程序协议 (BOOTP) 功能: 允许无盘 ...

  10. Go xmas2020 学习笔记 08、Functions, Parameters & Defer

    08-Functions, Parameters. functions. first class. function signatures. parameter. pass by value. pas ...