后缀数组

后缀数组

对于给定的字符串\(s\),构建两个数组\(sa\)\(rk\),其中\(rk[i]\)表示\(s[i,n]\)\(s\)的所有后缀中的字典序排名,\(sa[i]\)则表示排名\(i\)的后缀的最左端位置。容易发现有\(sa[rk[i]]=rk[sa[i]]=i\)

构造 - 倍增法

一般来说,我们用倍增法\(O(n\log n)\)构建出\(rk\)数组就可以了。

我们倍增考虑的长度\(k\)。当\(k>=n\)时退出。

  • 每次倍增开始前,你要保证这些后缀的排名是将他们“长度为\(k\)的前缀”排序后的排名。若两个字符串“长度为\(k\)的前缀”相同,则排名也应相同。
  • 然后把每个后缀\(i\)“以\(rk[i]\)为第一关键字、\(rk[i+k]\)为第二关键字”再次排序,更新\(rk\)数组。(对于越界的\(rk\)下标,你认为其值为\(-\infty\))这样你就得到了按“长度为\(2k\)的前缀“排序后的排名辣!

最开始时把所有后缀按它们的首字母排序,获得初始排名\(rk\)数组即可。

排序过程采用基数排序,则总复杂度为\(O(n\log n)\)

举个栗子:

b a n a n a
2 1 3 1 3 1 // k=1
3 2 4 2 4 1 // k=2
3 2 5 2 4 1 // k=4
4 3 6 2 5 1 // k=8

用途 - LCP(最长公共前缀)

我们令\(lcp(s_1, s_2)\)为字符串\(s_1, s_2\)的最长公共前缀。令\(LCP(i,j)=lcp(s[sa[i],n], s[sa[j],n])\)

那么我们有引理\(LCP-Lemma\)\(\forall i<j<k, LCP(i,k)=\min(LCP(i,j),LCP(j,k))\)

这样我们就得到了推论:\(LCP(i,j)=\sum\limits_{k=i+1}^j LCP(k-1,k)\),原问题转为\(RMQ\)。但不幸的是,\(LCP(k-1,k)\)你还只会\(O(n^2)\)预处理,这显然是不行的。

height 数组

我们设\(height[i]=LCP(i,i-1), h[i]=height[rk[i]]\),则\(height[1]=0\)。考虑如何高效求\(h\)数组。

有一个结论\(LCP-Theorem\)\(h[i]\ge h[i-1]-1\)

根据\(LCP-Theorem\),每次\(h[i]\)直接从\(h[i-1]-1\)开始大力枚举就好。复杂度\(O(n)\)

再举一个栗子:

s: b a n a n a
h: 0 3 2 1 0 0

a -> 0
ana -> 1
anana -> 3
banana -> 0
na -> 0
nana -> 2


引理及证明


引理LCP-Lemma

\(\forall i<j<k, LCP(i,j)=\min(LCP(i,j),LCP(j,k))\)

证明:设\(p=\min(LCP(i,j),LCP(j,k))\),则我们显然有\(p\ge LCP(i,k)\)

结合\(i<j<k\),我们可以知道:\(s[sa[i]+p]<s[sa[j]+p]\)\(s[sa[j]+p]<s[sa[k]+p]\)中至少一个成立。否则\(p<\min(LCP(i,j),LCP(j,k))\)并产生矛盾。
所以\(s[sa[i]+p]<s[sa[k]+p]\),故\(p\le LCP(i,k)\)。证毕。


定理LCP-Theorem

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

证明:当\(h[i-1]=0\)时,显然成立。下面讨论\(h[i-1]>0\)的情况。

\(k=sa[rk[i-1]-1]\),则\(h[i-1]=lcp(s[k,n], s[i-1,n])\),那么有\(\left\{\begin{array}{**lr**} h[i-1]-1=lcp(s[k+1,n], s[i,n])\\ rk[k+1]<rk[i] \end{array}\right.\)(这一步相当于把他们的首字符砍掉)。

结合\(LCP-Lemma\),可得

\[\begin{aligned} &lcp(s[k+1,n], s[i,n])\\ &=LCP(rk[k+1], rk[i]) \\ &= \min(LCP(rk[k+1], rk[i]-1), LCP(rk[i]-1, rk[i]))\end{aligned}\\ \therefore lcp(s[k+1,n], s[i,n])\le LCP(rk[i]-1, rk[i])\\ 即h[i-1]-1\le h[i],证毕。 \]

posted @ 2020-06-19 20:26  acniu  阅读(100)  评论(0编辑  收藏  举报