首页 > 其他分享 >后缀数组求 LCP 和相关证明

后缀数组求 LCP 和相关证明

时间:2024-11-01 15:47:48浏览次数:1  
标签:suf le LCP min 后缀 text rank 数组

后缀数组求 LCP 和相关证明

一些定义

\(\text{SA}(i)\) 排名为 \(i\) 的后缀左端点;\(\text{rank}(i)\) 左端点为 \(i\) 的后缀排名;\(\text{suf}(i)\) 左端点为 \(i\) 的后缀;

\(\text{lcp}(S,T)\),串 \(S\) 和 \(T\) 的最长公共前缀,即 \(\max \left \{ x |\forall y\le x, S_{y}=S_{y}\}\right.\);

\(\text{LCP}(i,j)\),排名为 \(i\) 的后缀和排名为 \(j\) 的后缀的最长公共前缀,即 \(\text{lcp}(\text{suf}(\text{SA}(i)),\text{suf}(\text{SA}(j)))\);

\(\text{height}(i)\),排名为 \(i\) 和 \(i-1\) 的后缀的最长公共前缀,即 \(LCP(i,i-1)\),特别地 \(\text{height}(1)=0\);

\(h(i)=\text{height(rank}(i))\)。

性质1

对于 \(1\le i \le n\),显然有:

\[\text{LCP}(i,i) = n-\text{SA}(i)+1 \]

\[\text{LCP}(i,j)=\text{LCP}(j,i) \]

定理 1

对于 \(1\le i < j \le n\),有:

\[\text{LCP}(i,j)=\min_{i<k\le j} \left \{ \text{LCP}(k,k-1) \} \right. \]

证明:


引理

对于 \(1\le i < j \le n\),有:

\[\text{LCP}(i,j)=\min\left \{ \text{LCP}(i,k),\text{LCP}(k,j) \} \right. \text{ } (i\le k\le j) \]

证明:

设 \(\min \left \{ \text{LCP}(i,k),\text{LCP}(k,j) \} \right. = p\),

则 \(\text{LCP}(i,k) \ge p,\text{LCP}(k+1,j)\ge p\),

所以 \(i\) 和 \(k\) 至少有前 \(p\) 位相等,\(k\) 和 \(j\) 至少有前 \(p\) 位相等,

所以 \(\text{LCP}(i,j) \ge p\);

又因为$ \min { \text{LCP}(i,k),\text{LCP}(k,j) } = p$,

设 \(\text{suf}(i)=a,\text{suf}(k)=b,\text{suf}(j)=c\),

则有 \(a_{p+1}\ne b_{p+1}\) 或 \(b_{p+1}\ne c_{p+1}\),

若 \(a_{p+1} \ne b_{p+1}\) 和 \(b_{p+1} \ne c_{p+1}\) 中仅有一个成立,显然有 \(a_{p+1}\ne c_{p+1}\),

又根据 \(i,j,k\) 的排名关系,有 \(a_{p+1}\le b_{p+1}\le c_{p+1}\),

若 \(a_{p+1} \ne b_{p+1}\) 和 \(b_{p+1} \ne c_{p+1}\) 均成立,假设 \(a_{p+1}=c_{p+1}\),

则有 \(a_{p+1}=b_{p+1}=c_{p+1}\),与条件矛盾,假设不成立,则 \(a_{p+1}\ne c_{p+1}\)

综上有 \(a_{p+1}\ne c_{p+1}\),所以 \(\text{LCP}(i,j)\le p\);

结合 \(\text{LCP}(i,j)\ge p\),有 \(\text{LCP}(i,j)=p=\min\left \{ \text{LCP}(i,k),\text{LCP}(k,j) \} \right.\),得证。


根据引理,可推出:

\[\text{LCP}(i,j)=\min\left \{ \text{LCP}(i,k),\text{LCP}(k,j) \} \right. \]

\[\text{LCP}(i,j)=\min \left \{ \text{LCP}(i,i+1),\text{LCP}(i+1,j) \} \right. \]

\[\text{LCP}(i,j)=\min \left \{ \text{LCP}(i,i+1),\min \left \{ \text{LCP}(i+1,i+2), \text{LCP}(i+2,j)\} \right. \} \right. \]

归纳可得:

\[\text{LCP}(i,j)=\min_{i<k\le j} \left \{ \text{LCP} (k,k-1)\} \right. \]

得证。

转化

\[\text{LCP}(i,j)=\min_{i<k\le j} \left \{ \text{LCP} (k,k-1)\} \right. = \min_{i<k\le j} \left \{\text{height}_k \} \right. \]

这样 \(\text{LCP}\) 问题就转化为区间最值(\(\text{RMQ}\))问题,可以使用 \(\text{ST}\) 表 \(O(n \log n)\) 预处理 \(O(1)\) 查询。

现在的问题就转化为了求 \(\text{height}\) 数组。

定理 2

对于 \(1<i\le n\),有:

\[h(i)\ge h(i-1)-1 \]

证明:


性质2

对于 \(1\le i,j < n,\text{lcp}(\text{suf}(i),\text{suf}(j))>1\),有:

\[\text{suf}(i)<\text{suf}(j) \Longleftrightarrow \text{suf}(i+1)<\text{suf}(j+1) \]

\[\text{lcp}(\text{suf}(i),\text{suf}(j))-1=\text{lcp}(\text{suf}(i+1),\text{suf}(j+1)) \]


定理 1 的引理的推论

对于 \(1\le i,j\le n\),有:

\[\text{LCP}(i,j)\le\text{LCP}(k,j) \text{ } (i\le k\le j) \]

证明:根据定理 1 的引理,显然成立。


当 \(h(i-1)\le 1\) 时,\(h(i)\ge 0\ge h(i-1)-1\),得证;

当 \(h(i-1) > 1\) 时,即 \(\text{height}(\text{rank}(i-1))>1\),

可推出 \(\text{rank}(i-1)>1\),因为 \(\text{height}(1)=0\),

令 \(j=i-1\),\(k=\text{SA(rank}(j)-1)\),有:

\(h(i-1)=\text{LCP}(\text{rank}(j),\text{rank}(k))=\text{lcp}(\text{suf}(j),\text{suf}(k))\),

\(\text{suf}(k)<\text{suf(j)}\),

因为 \(\text{lcp}(\text{suf}(j),\text{suf}(k)) = h(i-1)>1\),根据性质2有:

\(h(i-1)-1=\text{lcp}(\text{suf}(i),\text{suf}(k+1))\),

\(\text{suf}(k+1)<\text{suf}(i)\)

即 \(\text{rank}(k+1) < \text{rank}(i) \rightarrow \text{rank}(k+1)\le \text{rank}(i)-1\),

根据定理 1 的引理的推论得:

\[\begin{align} \text{LCP}(\text{rank}(i)-1,\text{rank}(i)) &\ge \text{LCP}(\text{rank}(k+1),\text{rank}(i)) \\ &=\text{lcp}(\text{suf}(i),\text{suf}(k+1)) \\ &= h(i-1)-1 \end{align} \]

又因为 \(\text{LCP}(\text{rank}(i)-1,\text{rank}(i))=h(i)\),所以 \(h(i)\ge h(i-1)-1\),得证。

具体求法

有了定理 2 后,就可求出 \(\text{height}\) 数组。

先考虑暴力的代码,即从头开始暴力匹配,时间复杂度 \(O(n^2)\)。

根据定理 2,\(h(i)\ge h(i-1)-1\),可以直接从 \(h(i-1)-1\) 开始匹配。

因为 \(h(i)\le n\),每次 \(h(i)\) 最多减一,所以时间复杂度 \(O(n)\)。

代码

void get_height() {
	for (int i = 1, k = 0, j; i <= n; i ++) {
		if (rk[i] == 1) continue; // height[1]=0
		k = k ? k - 1 : k; // h[i-1]-1
		for (j = sa[rk[i] - 1]; 
			i + k <= n && j + k <= n 
			&& S[i + k] == S[j + k]; k ++);
		height[rk[i]] = k; // k=h[i]=height[rk[i]]
	}
}

标签:suf,le,LCP,min,后缀,text,rank,数组
From: https://www.cnblogs.com/maniubi/p/18520423

相关文章

  • 单链表题+数组题(快慢指针和左右指针)
    @目录说明:本文章用于“单链表题+数组题”“链表”知识一、案例说明(使用快慢指针)问题1.1判断链表是否有环问题1.2:已知链表有环,请返回这个环的起点位置问题1.3:寻找无环单链表的中点,要求:如果偶数个数以左面一个节点为中点问题1.4:寻找无环单链表的中点,要求:如果偶数个数以右面一个节......
  • Leetcode—624. 数组列表中的最大距离【中等】
    2024每日刷题(198)Leetcode—624.数组列表中的最大距离实现代码classSolution{public:intmaxDistance(vector<vector<int>>&arrays){intm=arrays.size();intn=arrays[0].size();intmn=arrays[0][0];intmx=ar......
  • C语言中指针和数组的相互关系
    在C语言中,指针和数组有着紧密的相互关系。数组是数据的集合,而指针则是一个包含内存地址的变量。指针可以用来访问数组的元素,便于高效的内存访问和操作。更具体来说,数组名本身就是一个指向首元素的指针、通过指针运算,我们可以遍历数组的每个元素、数组和指针的索引操作是等价的、......
  • SS241031D. 后缀数组(sa)
    SS241031D.后缀数组(sa)题意重题:NOD2308D.飒妃客厮·啊瑞(array)给你一个初始\(a_i=i\)的长度为\(n\)的序列,\(n\le10^9\)。有\(m\)次操作。\(m\le10^5\)。把区间\([l,r]\)移到最前面。翻转区间\([l,r]\)。最终得到序列\(\{a_i'\}\)。求满足长度为\(n\)的......
  • 什么是指针数组 和 数组指针
    什么是指针数组答:就是一个数组,里面存的是指针而已它的写法可以如下:int*a[10];看看,它就是一个指针数组,数组名字当然是a,里面有10个元素,每个元素都是一个int*类型(即存放整型地址的指针)的指针。我们可以这样用,比如: #include<stdio.h>Cintmain(){intx=10,y=20,z=3......
  • 异或运算解决查找数组中出现奇数次元素
            假设有一个数组只有一个元素出现奇数次,需要查找这个出现奇数次的元素,怎么使用时间复杂度为O(n),空间复杂度为O(1),来解决这道题。以下是使用异或来解决这道题:publicstaticintselectOddTimesNum(int[]nums){intresult=0;for(intnum:nums......
  • 网站修改源文件后缀,如何安全地更改网站文件的后缀名
    备份文件:在修改之前,务必备份原文件,以防万一出现问题可以恢复。了解文件类型:确保你知道文件的实际类型,例如 .html 文件和 .php 文件有不同的处理方式。重命名文件:在文件管理器中右键点击文件,选择“重命名”,然后更改文件后缀名。例如,将 index.html 改为 index.php。测试......
  • c语言经典20例(输入数组元素,进行排序并输出)
    下面是C语言程序的文字讲解,该程序实现了输入数组元素、对其进行选择排序并输出排序后的数组。#include<stdio.h>voidselectionSort(intarr[],intn){inti,j,min_idx,temp;//一次移动未排序部分的边界for(i=0;i<n-1;i++){//找到......
  • 为什么 C 语言数组是从 0 开始计数的?
    C语言等大多数编程语言的数组从0开始而不从1开始,有两个原因:第一:地址计算更方便C语言从0开始的话,array[i]的地址就正好是:(array+i)如果是从1开始的话,就是(array+i-1)多一次计算,性能受影响,再扩展到二维数组的话array[i][j]从0开始的地址是:(ar......
  • 倍增求后缀数组
    倍增求后缀数组1.一些定义后缀\(i\):子串\([\text{len}(S)-i+1,\text{len}(S)]\);\(\text{SA}(i)\):排名为\(i\)的后缀;\(\text{rank}(i)\):后缀\(i\)的排名,\(\foralli>n,\text{rank}(i)=0\)。后缀数组即\(\text{SA}\)。2.求法先对每个单独的字符从小到大排序,得到每个......