首页 > 其他分享 >后缀数组 II —— height 数组及其求法

后缀数组 II —— height 数组及其求法

时间:2023-01-11 10:14:13浏览次数:51  
标签:lcp 后缀 height II ge 数组 sa operatorname rk

上集 : 后缀数组 I —— 后缀排序

记 \(S_i\) 表示以 \(i\) 为起点的后缀, \(sa_i\) 表示对 \(s\) 进行后缀排序后排名为 \(i\) 的后缀,\(SA_i\) 表示对 \(s\) 进行后缀排序后排名为 \(i\) 的后缀的起点,\(rk_i\) 表示对 $S_i $ 进行后缀排序后的排名,\(lcp(s_1,s_2)\) 代表 \(s_1\) 和 \(s_2\) 的最长公共前缀的长度。

我们接下来要考察关于所有后缀的 \(\operatorname{lcp}\) 的性质。

性质 \(1\) : \(\operatorname{lcp}(sa_i,sa_k)=\min(\operatorname{lcp}(sa_i,sa_j),\operatorname{lcp}(sa_j,sa_k))(i<j<k)\)。

下面简略证明,记 \(p=\min(\operatorname{lcp}(sa_i,sa_j),\operatorname{lcp}(sa_j,sa_k))\),可知 \(sa_i\) 和 \(sa_j\) 的前 \(p\) 位相等,\(sa_j\) 和 \(sa_k\) 的前 \(p\) 位相等。由此,\(sa_i\) 和 \(sa_k\) 的前 \(p\) 位相等,所以 \(\operatorname{lcp}(sa_i,sa_k)\ge p\)。

考虑分析 \(sa_i\) 和 \(sa_k\) 的第 \(p+1\) 位,记 \(sa_i,sa_j,sa_k\) 的第 \(p+1\) 位分别为 \(w_i,w_j,w_k\),分三种情况讨论:

  • \(\operatorname{lcp}(sa_i,sa_j)=\operatorname{lcp}(sa_j,sa_k)=p\),由此可得第 \(p+1\) 位 \(sa_i\) 和 \(sa_j\) 不同,而之前的 \(p\) 位都相同,并且 \(sa_i\) 的排名显然高于 \(sa_j\),所以有 \(w_i<w_j\),同理有 \(w_j<w_k\),从而有 \(w_i<w_k\)。

  • \(\operatorname{lcp}(sa_i,sa_j)>\operatorname{lcp}(sa_j,sa_k)=p\),有 \(w_i=w_j\),有 \(w_j<w_k\),从而有 \(w_i<w_k\)。

  • \(\operatorname{lcp}(sa_j,sa_k)>\operatorname{lcp}(sa_i,sa_j)=p\),有 \(w_i<w_j\),有 \(w_j=w_k\),从而有 \(w_i<w_k\)。

可以发现,无论如何总有 \(w_i<w_k\),从而有 \(\operatorname{lcp}(sa_i,sa_j)\leq p\),又因为 \(\operatorname{lcp}(sa_i,sa_j)\ge p\),故得证。

性质 \(2\) : \(\operatorname{lcp}(sa_i,sa_j)=\min\limits_{k=i+1}^j\operatorname{lcp}(sa_{k-1},sa_k)(i<j)\)。

这个性质由性质 \(1\) 可以简单推得,考虑根据这个性质定义一个数组 \(height_i=\operatorname{lcp}(sa_{i-1},sa_i)\),式子变成了 \(\operatorname{lcp}(sa_i,sa_j)=\min\limits_{k=i+1}^j height_k\),通过这一步转化。我们将求 \(\operatorname{lcp}\) 转化为了求区间 \(\min\),毫无疑问,这十分有用。

性质 \(3\) : \(\operatorname{lcp}(sa_j,sa_i)\ge\operatorname{lcp}(sa_k,sa_i)(k\leq j\leq i)\)。

这个性质由性质 \(2\) 可以简单推得,这个性质说明了 \(\operatorname{lcp}\) 在固定右端点的情况下满足单调性。

接下来我们还面临着一个问题,我们在性质 \(2\) 中引入了 \(height\) 数组,但是如何求 \(height\) 数组呢?

有一种较为暴力的 \(O(n\log n)\) 的方法,即 hash + 二分,时间复杂度方面由于后缀数组本身自带 \(\log\) 完全不会成为复杂度瓶颈。

不过,存在一种巧妙的 \(O(n)\) 求解方法。

记 \(h_i=height_{rk_i}\),即 \(h_i\) 代表 \(S_i\) 与 \(sa_{rk_i-1}\) 的最长公共前缀。

接下来我们需要证明 \(h_i\ge h_{i-1}-1\)。

当 \(h_{i-1}\leq1\) 时,显然成立。

当 \(h_{i-1}>1\) 时,考虑 \(h_{i-1}-1\) 的意义是什么,即将 \(S_{i-1}\) 的开头字符抹掉之后的最长公共前缀,我们发现,将 \(S_{i-1}\) 的开头字符抹掉即 \(S_i\),另一个后缀同理,可得 \(h_{i-1}-1=\operatorname{lcp}(S_i,S_{SA_{rk_{i-1}}+1})\)。

所以证明 \(h_i\ge h_{i-1}-1\) 变成了证明 \(\operatorname{lcp}(sa_{rk_i-1},S_i)\ge\operatorname{lcp}(S_{SA_{rk_{i-1}}+1},S_i)\)。

由于 \(S_{i-1}>sa_{rk_{i-1}-1}\),而它们又有公共前缀 (因为有条件 \(h_{i-1}>1\)),所以将第一个字符删掉之后,仍保持单调性,故有 \(S_i>S_{SA_{rk_{i-1}}+1}\),又因为 \(sa_{rk_i-1}\) 的排位仅在 \(S_i\) 前一位,而 \(S_{SA_{rk_{i-1}}+1}\) 的排位在 \(S_i\) 前,所以一定有 \(S_{SA_{rk_{i-1}}+1}\leq sa_{rk_i-1}\),根据性质 \(3\) 有 \(\operatorname{lcp}(sa_{rk_i-1},S_i)\ge\operatorname{lcp}(S_{SA_{rk_{i-1}}+1},S_i)\),从而 \(h_i\ge h_{i-1}-1\) 得证。

根据这个性质,我们可以得到 \(h\) 数组的求法,即暴力,我们在暴力计算 \(h_i\) 的时候已经知道前 \(h_{i-1}-1\) 位一定不用看,暴力往后匹配,若未能匹配成功则停止,由均摊分析可知总复杂度为 \(O(n)\)。

标签:lcp,后缀,height,II,ge,数组,sa,operatorname,rk
From: https://www.cnblogs.com/Miracle-blog/p/17042935.html

相关文章

  • Heightchars 图标插件
    官网地址  https://www.runoob.com/highcharts/highcharts-setting-detail.html带数字的折线图:1html>2<head>3<metacharset="UTF-8"/>4<title>Highchar......
  • 找出整型数组中重复次数最多元素集合中的最小值
    考虑用map去处理,然后筛选出map里值最大的元素集合,最后集合中键最小的那个元素  importjava.util.*;importjava.util.stream.Collectors;publicclassMain{......
  • 122. 买卖股票的最佳时机II
    问题链接https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/解题思路买卖股票,本质上就是低价买入,高价卖出。我们可以用模拟法,不断的去找到......
  • Day11:数组基础知识
    packagecom.dfyfhqsgclxry.array;publicclassArrayDemo08{publicstaticvoidmain(String[]args){//1.创建一个二维数组11*11,0:没有棋子1:黑棋2:白棋int[......
  • 45. 跳跃游戏II
    问题链接https://leetcode.cn/problems/jump-game-ii/解题思路这个题目,乍一看挺难,其实我们想一下就可以知道,我们如果从后往前推,有潜质跳到最后一个数字的格子,且有潜质跳......
  • leetcode215-数组中的第K个最大元素
    思路我自己想到的是用排序,然后取下标为n-k的数字,但是这样时间复杂度是O(nlogn),不符合题目要求题解中的快速排序法很好,我也想到了快速排序,但是具体实现没有写出来要点......
  • IIS配置URL_Rewrite详细步骤
    1.URL_Rewrite下载地址https://www.iis.net/downloads/microsoft/url-rewrite 2.WebConfig配置需要配置在 <system.webServer> 这个节点中  <rewrite>  ......
  • solidity 内存(memory) 可变数组的增删改查 操作
    //SPDX-License-Identifier:MITpragmasolidity^0.8.9;libraryArray{functionpush(uint256[]memory_nums,uint256_num)internalpure{assemb......
  • leetcode简单(数组,字符串,链表):[168, 171, 190, 205, 228, 448, 461, 876, 836, 844]
    目录168.Excel表列名称171.Excel表列序号190.颠倒二进制位205.同构字符串228.汇总区间448.找到所有数组中消失的数字461.汉明距离876.链表的中间结点836.矩形重......
  • 40. 组合总和 II
    40.组合总和II难度中等1200给定一个候选人编号的集合candidates和一个目标数target,找出candidates中所有可以使数字和为target的组合。candidates中的每个数......