[学习笔记]后缀数组(Suffix Array)

news/2025/3/16 18:48:02/文章来源:https://www.cnblogs.com/xm-blog/p/18340581

后缀数组(suffix array)是一个通过对字符串的所有后缀经过排序后得到的数组。后缀数组被 Manber 和 Myers 于1990年提出, 作为对后缀树的一种替代, 更简单以及节省空间。它们也被Gaston Gonnet 于1987年独立发现, 并命名为“PAT数组”。

后缀数组有很多奇妙的性质, 这些性质可以帮助解决很多字符串问题(然后出串串题虐死别人)

板子题:

P3809 【模板】后缀排序

\(O(n \log^2 n)\) 做法

后缀 \(i\) 代指以第 \(i\) 个字符开头的后缀, 也称 \(suff(i)\), 本文规定字符串下标从 \(1\) 开始, 后文都将使用数组式下标。

首先朴素的想, 将 \(n\) 个后缀直接塞进 string 数组内大力 sort, 很不幸 STL 提供的 string 类型比较字典序的复杂度为 \(O(n)\), 我们只能得到 \(O(n^2 \log n)\) 的暴力。

回想一下我们比较字符串的字典序的过程:

1.从第一个字符开始比较。

2.如果当前字符不相等,就直接比较这两个字符,即可得出答案。

3.否则,继续比较下一个字符。

这个过程实际上就是在寻找两个字符串的最长公共前缀,而下一个字符就一定不相等。最长公共前缀是具有单调性的,哈希上二分一下就能 \(O(\log n)\) 比较字典序,这样我们的算法就优化到了 \(O(n \log^2 n)\)。这个复杂度已经可以通过洛谷的模板题了(代码)。

复杂度瓶颈在排序和求 \(LCP\), 不好优化, 考虑另一种 \(O(n \log^2 n)\) 的做法:

先按照每个后缀的第一个字符排序。对于每个字符,我们按照字典序给一个排名(当然可以并列), 这里称作关键字。

接下来我们再把相邻的两个关键字合并到一起,就相当于根据每一个后缀的前两个字符进行排序。想想看,这样就是以第一个字符(也就是自己本身)的排名为第一关键字,以第二个字符的排名为第二关键字,把组成的新数排完序之后再次标号。没有第二关键字的补零。

既然是倍增,就要有点倍增的样子。接下来我们对于一个在第 i 位上的关键字,它的第二关键字就是第 (i+2) 位置上的,联想一下,因为现在第 i 位上的关键字是 \(suff(i)\) 的前两个字符的排名,第 i+2 位置上的关键字是 \(suff(i+2)\) 的前两个字符的排名,这两个一合并,不就是 \(suff(i)\) 的前四个字符的排名吗?方法同上,排序之后重新标号,没有第二关键字的补零。同理我们可以证明,下一次我们要合并的是第 i 位和第 i+4 位,以此类推即可……

那么我们什么时候结束呢?很简单,当所有的排名都不同的时候我们直接退出就可以了,因为已经排好了。最多倍增 \(O(\log n)\) 次,使用 sort 排序,总复杂度 \(O(n \log^2 n)\)

这种方法的常数远小于上一种方法, 因为倍增中每次排序都会使后缀数组更有序, sort 越有序跑得越快, 有序后可以提前退出, 所以跑不满 O(n \log^2 n) (代码)。

\(O(n \log n)\) 做法

复杂度还是一样, 复杂度瓶颈是倍增和排序好像也没啥变化, 除了常数变小, 这种做法还有什么好处吗?

当然有!排序的关键字变为了上一次排序的排名, 排名是 \(O(n)\) 的, 聪明的同学们应该立刻想到计数排序。关键字有两个也好办, 多关键字计数排序就是基数排序, 常数个关键字的基数排序时间复杂度还是 \(O(n)\), 排序两次就成了。

因为两次计数排序需要很多转换, 代码里很多层循环, 总复杂度是常数略大的 \(O(n \log n)\), 并没有与上面的小常数 \(O(n \log^2 n)\) 拉开太大差距。

\(O(n)\) 做法

还没有学,先在这里挖个坑,以后学了再补。

参考:

洛谷题解

oiwiki

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

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

相关文章

2023 福建省第三届工业互联网创新大赛CTF Misc-Covertchannel2

2023 福建省第三届工业互联网创新大赛CTF Misc-Covertchannel2题目:近日,公司Windows服务器被入侵,黑客使用了一个比较隐蔽的信道将机密凭据传输了出去,但是蛛丝马迹还是被流量采集设备捕获了,你能从中找回丢失的flag吗?分析: 分析该流量包发现了有一个 rsa.key,并且在…

mybatis 源码环境搭建

参考 从头到尾手把手教你搭建阅读Mybatis源码的环境(程序员必备技能) Cannot enable lazy loading because Javassist is not available. Add Javassist to your classpath. 下载源码 https://github.com/mybatis/mybatis-3/ https://github.com/mybatis/parent/tree/mybatis-p…

05、Pod网络

4.1 Pod网络 在K8s集群中,多个节点上的Pod相互通信,要通过网络插件来完成,比如Calico网络插件。 使用kubeadm初始化K8s集群时,有指定一个参数 --pod-network-cidr=10.18.0.0/16 它是用来定义Pod的网段。 而我们在配置Calico的时候,同样也定义了一个CALICO_IPV4POOL_CIDR的…

Ros2 Moveit2 之 围绕对象进行规划 - 添加障碍物

本教程将向您介绍如何将对象插入规划场景并围绕它们进行规划。 先决条件 如果您还没有这样做,请确保您已完成RViz 中的可视化hello_moveit中的步骤。本项目假设您从上一个教程结束的地方开始。如果您只想运行本教程,您可以按照Docker 指南启动一个包含已完成教程的容器。 步骤…

使用 clearError 清除已处理的错误

title: 使用 clearError 清除已处理的错误 date: 2024/8/5 updated: 2024/8/5 author: cmdragon excerpt: 摘要:“文章介绍了clearError函数的作用与用法,用于清除已处理的错误并可实现页面重定向,提升用户体验。通过示例展示了在表单提交场景中如何应用此函数进行错误处理…

破局SAP实施难题、降低开发难度,定制化需求怎样快速上线?

前言 SAP 是全球领先的业务流程管理软件供应商之一,其提供广泛的模块化解决方案和套件,所开发的软件解决方案面向各种规模的企业,帮助客户规划和设计业务流程、分析并高效设计整个价值链,以更好的了解和响应客户需求。ERP 是企业资源规划的简称,ERP 软件涵盖所有核心业务领…

ComplatebleFuture异步调用方法,喝茶你也可以很快

ComplatebleFuture的异步用法: ComplateFuture.supplyAsync()方法会将方法体里面的方法进行异步调用,不用一直等待; ComplateFuture.allof()方法用于等待所有complatebleFutrue方法执行完毕。

若依框架导入阿里OSS报错问题解决方案

1、首先使用终端查看java JDK版本号 java -version 输出结果: java version "1.8.0_361" Java(TM) SE Runtime Environment (build 1.8.0_361-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.361-b09, mixed mode) javac-version 输出结果: javac 1.8.0_361 如…

php---空合并运算符

在做PHP开发的过程中,在引入SDK做项目开发的时候,经常会遇到一些不常见的运算符,正好自己也学习一下。运行的结果:就比如上面看到的运算符 ?: 和 ?? 运算符和我们常见的三目运算符不同,但是也有点类似。 三目运算符是这样的:$abs = !empty($list) ? a : b;而空合并运…

玄机

第一章 应急响应-webshell查杀 靶机账号密码 root xjwebshell 1.黑客webshell里面的flag flag{xxxxx-xxxx-xxxx-xxxx-xxxx} 2.黑客使用的什么工具的shell github地址的md5 flag{md5} 3.黑客隐藏shell的完整路径的md5 flag{md5} 注 : /xxx/xxx/xxx/xxx/xxx.xxx 4.黑客免杀马完整…

Spring Boot 基于 SCRAM 认证集成 Kafka 的详解

在本篇文章中,我们将探讨如何在Spring Boot应用中集成Kafka并使用SCRAM认证机制进行安全连接;并实现动态创建账号、ACL 权限、Topic,以及生产者和消费者等操作。一、说明 在现代微服务架构中,Kafka 作为消息中间件被广泛使用,而安全性则是其中的一个关键因素。在本篇文章中…