SAM[详细~bushi]
基础性质概念
- 后缀自动机: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]的更多相关文章
- sam格式详细说明
原文链接 https://www.jianshu.com/p/386f520e5de1 The SAM Format Specification(sam格式说明) 1 The SAM Format S ...
- [转]后缀自动机(SAM)
原文地址:http://blog.sina.com.cn/s/blog_8fcd775901019mi4.html 感觉自己看这个终于觉得能看懂了!也能感受到后缀自动机究竟是一种怎样进行的数据结构了. ...
- Linux中find、grep命令详细用法
在linux下面工作,有些命令能够大大提高效率.本文就向大家介绍find.grep命令,他哥俩可以算是必会的linux命令,我几乎每天都要用到他们.本文结构如下: find命令 find命令的一般形式 ...
- 初创互联网公司简明创业指南 - YC新掌门Sam Altman
本文只是一个创业指南的简明版 - 更详细的版本请查看:http://startupclass.samaltman.com 创业之前,你更应该去拥有一个好的创意,而不是一个公司.如果开始前你拥有一个好的 ...
- SAMTOOLS使用 SAM BAM文件处理
[怪毛匠子 整理] samtools学习及使用范例,以及官方文档详解 #第一步:把sam文件转换成bam文件,我们得到map.bam文件 system"samtools view -bS m ...
- Luogu P3181 [HAOI2016]找相同字符 广义$SAM$
题目链接 \(Click\) \(Here\) 设一个串\(s\)在\(A\)中出现\(cnt[s][1]\)次,在\(B\)中出现\(cnt[s][2]\)次,我们要求的就是: \[\sum cnt ...
- SAM文件格式
帮朋友处理sam各式文件,又记不住sam各式每列代表的什么内容,干脆转个帖子留着以后查询. 在SAM输出的结果中每一行都包括十二项通过Tab分隔,从左到右分别是: 1 序列的名字 2 概括出一个合适的 ...
- 后缀自动机(SAM)速成手册!
正好写这个博客和我的某个别的需求重合了...我就来讲一讲SAM啦qwq 后缀自动机,也就是SAM,是一种极其有用的处理字符串的数据结构,可以用于处理几乎任何有关于子串的问题,但以学起来异常困难著称(在 ...
- 【H3C交换机】cpu各个进程的详细说明
display cpu-usage命令用来查看设备CPU占用率的统计信息,以及各个进程的cpu占用率. 各个进程详细说明如下,不同软件版本.盒式和框式的cpu进程略有不同,详细信息可以查看手册中的命令 ...
随机推荐
- 中小学数学卷子自动生成程序--对G同学的代码分析
前几天,在课程要求下完成了个人项目的项目工程编写,即一个中小学数学卷子自动生成程序. 程序主要功能是用户预设账户登录后可以选择等级进行对应的小中高的数学卷子对应出题生成txt文本. 本文针对partn ...
- Django实现统一包装接口返回值数据格式
前言 最近实在太忙了,开始了一个新的项目,为了快速形成产品,我选择了Django来实现后端,然后又拿起了之前我封装了项目脚手架「DjangoStarter」. 由于前段时间我写了不少.NetCore的 ...
- linux磁盘概述
硬盘简史 世界上第一块硬盘出生在1956年,至今已有61年半个多世纪的历史.它由IBM公司制造,世界上第一块硬盘:350RAMAC.盘片直径为24英寸,盘片数为50片,重量则是上百公斤,相当于两个冰箱 ...
- Linux磁盘分区fdisk命令操作(简洁版)
实例(环境为: CentOS Linux release 7.2.1511 (Core), 3.10.0-327.el7.x86_64) 选择要具体操作的第二块磁盘(linux下一切是文件形式对应): ...
- Docker部署Nginx启动成功,浏览器拒绝访问
今天下午部署完tomcat和mysql之后就接着部署Nginx,本以为Nginx也和之前两个一样简单,但是就因为标题这个问题,花费了我一个小时纠错. 过程复现: 解决完上一篇博客(https://ww ...
- Centos7 搭建 Socks 服务
Centos7 搭建 Socks 服务 一丶拿到一个动态拨号的服务器还不能使用网络得先打开: pppoe-start 二丶安装命令汇总: 通过yum安装ss5 依赖包: yum install gcc ...
- TemplatesImpl利用链
FastJson利用链 Fastjson的版本在1.2.22-1.2.24主要有两条链利用TemplatsImpl和JdbcRowSetImpl利用链先来学习TemplatsImpl利用链,这个与前面 ...
- POJ - 1321 A - 棋盘问题
A - 棋盘问题 http://poj.org/problem?id=1321 思路:不能搞双重循环嵌套,要注意可以跳过某行 代码 #include <cstdio> #include & ...
- Caused by: com.sonatype.nexus.staging.client.StagingRuleFailuresException: Staging rules failure! 已解决!
问题分析 由于项目中修改了一些代码,然后没有修改版本号,直接deploy代码到仓库,最终导致错误! 根据 https://central.sonatype.org/faq/can-i-change-a ...
- kafka从入门到了解
kafka从入门到了解 一.什么是kafka Apache Kafka是Apache软件基金会的开源的流处理平台,该平台提供了消息的订阅与发布的消息队列,一般用作系统间解耦.异步通信.削峰填谷等作用. ...