模板:后缀自动机(SAM)

所谓后缀自动机,就是通过后缀建立的自动机

(逃)
请允许我先介绍一下后缀家族:
在这里插入图片描述
(又逃)

前言

OI生涯目前为止学习的最为难以理解的算法,没有之一。
到现在也没有完全的理解。
qwq

概念

定义:

后缀 iii :字符串 sssiii 结尾的后缀(前缀同理)
endpos(x)endpos(x)endpos(x) 字符串 xxxsss 中出现的结尾位置的集合
等价类:若 endpos(u)=endpos(v)endpos(u)=endpos(v)endpos(u)=endpos(v),我们就称 uuuvvv 属于同一个等价类

不难发现,对于 sss 的一个子串 x=sl...rx=s_{l...r}x=sl...r,都存在一个位置 p∈(l,r]p\in (l,r]p(l,r],满足对于 l≤i≤pl\le i\le plipxxx 的后缀 iii 都与 xxx 属于同一个等价类,而对于 p<i≤rp<i\le rp<ir,后缀 iiixxx 都不属于一个等价类。
我们称满足这个性质的 ppplink(x)link(x)link(x)

SAM是一个字符转移边组成的DAG,每条从根结点出发的路径都唯一对应 sss 的一个子串,在SAM中,每个结点都对应着一个等价类的集合(也就是从根结点到该结点的路径所代表的字符串的集合,这些字符串必然由一个最长的字符串和它的一些连续的后缀组成),一个结点的 linklinklink 定义为该结点对应的最长字符串的 linklinklink

请务必确保你理解了上面这段话

构建

现在考虑如何构建出SAM
使用增量法,当前加入一个新的字符串 ccc
设上一个加入的结点为 lstlstlst,当前加入结点为 curcurcur
设一个结点代表的最长字符串的长度为 lenlenlen

首先,令 len(cur)←len(lst)+1len(cur)\gets len(lst)+1len(cur)len(lst)+1
然后从 lstlstlst 沿着 linklinklink 不断往上跳,直到跳到某个有 ccc 的转移边或者跳到根为止,沿途把 ccc 的转移边全部赋值成 curcurcur

situation 1

若到根了还没有 ccc 的转移边:说明整个字符串还没有出现过 ccc,直接把 link(cur)link(cur)link(cur) 赋值成根即可

否则,设跳到了结点 ppppppccc 转移边为 qqq
由于一直跳的是

situation 2

len(q)=len(p)+1len(q)=len(p)+1len(q)=len(p)+1:这两个结点在原串上就是相邻的,直接令 link(cur)=link(q)link(cur)=link(q)link(cur)=link(q) 即可

situation 3

len(q)≠len(p)+1len(q)\ne len(p)+1len(q)=len(p)+1:这两个结点在原串上不是相邻的,此时若按照情况2的处理方法,会使SAM上出现不应该出现的前缀,所以我们应该分裂出一个结点 pppppp,继承所有 qqq 的信息,len(pp)←len(p)+1len(pp)\gets len(p)+1len(pp)len(p)+1,并把 qqqcurcurcurlinklinklink 全指向 pppppp,再一路往上把本来连向 qqq 的转移连向 pppppp

代码

void ins(int c){c-='a';int cur=++tot,p=lst;lst=tot;st[cur].len=st[p].len+1;siz[cur]=1;for(;p&&!st[p].tr[c];p=st[p].fa) st[p].tr[c]=cur;if(!st[p].tr[c]) st[cur].fa=1;else{int q=st[p].tr[c];if(st[q].len==st[p].len+1) st[cur].fa=q;else{int pp=++tot;st[pp]=st[q];st[pp].len=st[p].len+1;st[q].fa=st[cur].fa=pp;for(;p&&st[p].tr[c]==q;p=st[p].fa) st[p].tr[c]=pp;return;}}
}

应用

求 endpos 集合大小

定义 sizxsiz_xsizx 为结点 xxx 的等价类集合中 endposendposendpos 的数目。(也就是出现次数)
那么根据定义,有:
sizx=∑s∈sonxsizs+[x∈S]siz_x=\sum_{s\in son_x} siz_s+[x\in S]sizx=ssonxsizs+[xS]
其中 SSS 是每次插入的终点集合
dfs或者拓扑实现均可

int cnt[N],id[N];
void calc(){for(int i=1;i<=tot;i++) ++cnt[st[i].len];for(int i=1;i<=n;i++) cnt[i]+=cnt[i-1];for(int i=tot;i>=1;i--) id[cnt[st[i].len]--]=i;for(int i=tot;i>=1;i--) siz[st[id[i]].fa]+=siz[id[i]];return;
}

求本质不同子串数

就是在自动机上的走法种类呗。
那么就有:
sumx=∑s=trx,csums+1sum_x=\sum_{s=tr_{x,c}}sum_s+1sumx=s=trx,csums+1

Thanks for reading!

后缀树

本身也是一个大算法,但是可以通过反串建SAM偷懒。
复杂度为 O(nC)O(nC)O(nC)

解析

对反串建出后缀自动机,其 failfailfail 树即为所求的后缀树。
plxpl_xplx,为 xxx 节点对应的任意一个出现位置,那么 failx→xfail_x\to xfailxx 这条边上对应的字符串就是 s(plx+lenfailx,plx+lenx−1)s(pl_x+len_{fail_x},pl_x+len_x-1)s(plx+lenfailx,plx+lenx1)
结合 failfailfail 的定义应该不难得到。

后缀树的性质:

  1. 根到叶子的路径和所有后缀一一对应。
  2. 所有非根节点都至少有两个子节点。
  3. LCP(i,j)LCP(i,j)LCP(i,j) 就是两个位置对应节点 lca 的最长长度。

在解决字典序相关问题时较为常用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317263.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET 开源项目 Anet 介绍

使用 Anet 有一段时间了&#xff0c;已经在我的个人网站&#xff08;如 bookist.cc&#xff09;投入使用&#xff0c;目前没有发现什么大问题&#xff0c;所以才敢写篇文章向大家介绍。GitHub 地址&#xff1a;https://github.com/anet-team/anetAnet 是一个 .NET Core 通用框架…

我的十年创业路

记十年创业的心路历程和我的创业思辨导读1 为什么写这篇文章2 详细的总结和思辨 2.01 感恩 2.02 为什么创业 2.03 十年流水账 2.04 经历了哪些失败 2.05 重要的职场基础 2.06 持续的学习和进步 2.07 创业与兴趣 2.08 价值观的碰撞和选择 2.09 合作与…

DotNetty 实现 Modbus TCP 系列 (一) 报文类

Modbus TCP/IP 报文报文最大长度为 260 byte (ADU 7 byte MBAP Header 253 byte PDU)Length Unit Identifier 长度 PDU 长度MBAP HeaderPDUPDU 由两部分构成&#xff1a;Function Code(功能码) 和 Data 组成Function Code部分功能码&#xff1a;报文类ModbusHeaderModbusHe…

专题突破三之并查集Ⅰ——Portal,parity,食物链,程序自动分析,Almost Union-Find,洞穴勘测

文章目录Portalparity[NOI2001] 食物链程序自动分析UVA11987 Almost Union-Find[SDOI2008] 洞穴勘测Portal source 百度翻译简直就是个鬼…(((m -__-)m 离线 将边和询问按权值排序&#xff0c;指针&#xff0c;将所有权值不超过当前询问iii的边全加进去 答案路径自然是不连…

C# 未来新特性:静态委托和函数指针

C# 每发布一次新版本&#xff0c;都会增加一些底层相关的新特性&#xff0c; 这些特性对大多数商业程序来说并没什么实际用处&#xff0c;主要用于那些对性能有很高要求的代码&#xff0c;如图形处理、机器学习以及数学工具包&#xff0c;等等。接下来的两个提案&#xff0c;主…

JavaWeb --第一章Web基本概念

JavaWeb --第一章Web基本概念 文章目录基本概念前言web开发&#xff1a;web应用程序静态web动态webweb服务器技术讲解web服务器基本概念 前言 web开发&#xff1a; web&#xff0c;网页的意思静态web a. html&#xff0c;css b. 提供给所有人看的数据始终不会发生改变动态we…

DotNetty 实现 Modbus TCP 系列 (二) ModbusFunction 类图及继承举例

DotNetty 实现 Modbus TCP 系列 (一) 报文类ModbusFunction 类图如下&#xff1a;如前文所述&#xff0c;所有请求/相应的 PDU 均继承自 ModbusFunction&#xff0c;其子类传入对应的 Function Code 并实现三个方法&#xff1a;CalculateLength&#xff1a;Data 部分的长度(该方…

专题突破三之并查集Ⅱ——星球大战,In Touch,方格染色,Junk-Mail Filter,关押罪犯,Silver Woods,Must Be Rectangular!

文章目录[JSOI2008]星球大战In Touch方格染色Junk-Mail Filter[NOIP2010 提高组] 关押罪犯Silver WoodsMust Be Rectangular![JSOI2008]星球大战 source 非常套路的&#xff0c;正着打击星球&#xff0c;逆着就是添加星球以及关系&#xff0c;并查集维护此时连通块个数 就是…

JavaWeb --第二章 Tomact详情

JavaWeb --第二章 Tomact详情 文章目录Tomcat安装TomcatTomcat启动和配置配置发布一个web网站Tomcat 安装Tomcat 去官方下载 https://tomcat.apache.org Tomcat启动和配置 文件夹作用&#xff1a; 启动/关闭 Tomcat&#xff1a; 文件夹bin/startup.bat 开启 网址&#x…

开源的类似于Apache ab的压力测试命令行工具SuperBenchmarker

SuperBenchmarker 是ㄧ个开源的类似于Apache ab的压力测试命令行工具。可以在 .NET 4.52 或者 .NET Core 2.0 平台上运行。可支持Get、Post、Put、Delete这些调用方式&#xff0c;调用时能指定Concurrent user、Request数、Header template…等。可以从Github、Chocolatey这两种…

如何优雅的利用Windows服务来部署ASP.NET Core程序

上一篇文章中我给大家讲述了五种部署ASP.NET Core网站的方法&#xff0c;其中有一种方式是通过Windows服务来进行部署&#xff0c;这样既可以做到开启自启动&#xff0c;又不会因为iis的反向代理而损失部分性能。但是美中不足的是需要借助第三方软件nssm来进行&#xff0c;那么…

JavaWeb --第四章Maven详解

JavaWeb --第四章Maven详解 文章目录MavenMaven架构管理工具下载安装Maven配置环境变量阿里云镜像本地仓库在IDEA中使用Maven创建一个普通的Maven项目在IDEA中标记文件夹功能在IDEA中配置tomcatpom文件IDEA操作解决遇到的问题Maven 为什么要学这个技术&#xff1f; 在javaweb…

用StyleCop规范团队代码

前言编码风格&#xff0c;每个人都是有不同的特点&#xff0c;风格各异&#xff0c;而且一个人在不同的时期&#xff0c;编码风格的差异也可能是非常大的&#xff0c;好比学生时代&#xff0c;刚工作的时候&#xff0c;工作一段时间后等。在一个团队中&#xff0c;或一个项目中…

一键发布部署vs插件[AntDeploy],让net开发者更幸福

一键发布工具(ant deploy tool)插件下载地址&#xff1a;https://marketplace.visualstudio.com/items?itemNamenainaigu.AntDeploy1.iis一键发布自动部署 (iis deploy support)支持netcore 和 netframework发布 (支持mvc webapi)支持website自动创建ps:需要在windows 服务器上…

计算几何全家桶

文章目录前言精度点/向量相关表示向量基本运算角度相关向量夹角旋转直线/线段相关表示点与线求点到直线垂足求点关于直线的对称点点与直线的位置关系点与直线的距离线与线直线与直线的位置关系共线与垂直判断线段与线段是否相交求直线与直线的交点角平分线中垂线多边形表示求多…

什么是量子计算机?用一个简单例子来解释

译者&#xff1a;王亮 作者&#xff1a;YK Sugi 原文&#xff1a;http://t.cn/EZAElk0Hi&#xff0c;大家好&#xff01;不久前&#xff0c;我参观了加拿大温哥华的D-Wave Systems公司&#xff0c;这是一家制造前沿量子计算机的公司。我在那里学到了很多关于量子计算机的知识&a…

解决Azure DevOps部署到Azure后.NET Core网站无法启动的问题

点击上方蓝字关注“汪宇杰博客”最近我遭遇了一个奇怪的问题。使用Azure DevOps配置CI/CD管线&#xff0c;自动部署到Azure App Service以后&#xff0c;.NET Core的网站竟然会启动失败。我们来看看如何解决这个问题。查找问题首先&#xff0c;幸好&#xff0c;这是个staging环…

Acwing 135 最大子序和

Acwing 135 最大子序和 题目&#xff1a; 输入一个长度为 n 的整数序列&#xff0c;从中找出一段长度不超过 m 的连续子序列&#xff0c;使得子序列中所有数的和最大。 题解&#xff1a; 我们把这个问题的集合分成n份&#xff0c;第k份表示以A[k]结尾的最大连续子序列是多少…

.net core自定义高性能的Web API服务网关

网关对于服务起到一个统一控制处理的作用&#xff0c;也便于客户端更好的调用&#xff1b;通过网关可以灵活地控制服务应用接口负载&#xff0c;故障迁移&#xff0c;安全控制&#xff0c;监控跟踪和日志处理等。由于网关在性能和可靠性上都要求非常严格&#xff0c;所以针对业…

微软宣布 Visual Studio 2019 将于4月2日正式发布

微软于去年发布了 Visual Studio 2019 预览版。今天&#xff0c;该公司宣布 Visual Studio 2019 正式版将于4月2日发布。微软在公告中表示&#xff1a;“欢迎加入我们在4月2号当天举办的 VS 2019 线上发布活动&#xff0c;这是一款更加现代化、创新且实用的生产力工具”。据悉&…