后缀数组的应用

后缀数组的应用

记 “后缀 \(i\)” 为 \(s[i,n]\)

\(sa[i]\) 表示字典序排名第 \(i\) 的后缀,\(rk[i]\) 表示后缀 \(i\) 的字典序排名。

\(height[i]=LCP(sa[i],sa[i-1])\)。特别地,\(height[1]=0\)

与 Trie 树

考虑将 \(s\) 的所有后缀插入到一棵 Trie 树 \(T\) 中。

\(sa\) 就是后缀按照 \(T\)\(dfn\) 序排序后的结果;\(height\) 就是 \(dfn\) 序相邻的两个后缀在 \(T\)\(LCA\) 的深度。

height 的 LCP最大性

推论:\(height[i]\) 即为 \(T\) 中的 \(\max_{rk[j]<rk[i]} \{dep(LCA(i,j))\}\),对应着 \(\max_{rk[j]<rk[i]}\{LCP(i,j)\}\)

height 引理

对于任意的 \(2\leq i\leq n\),有 \(height[rk[i]]\geq height[rk[i-1]]-1\)

证明

\(height[rk[i-1]]\leq 1\) 时显然成立。

\(height[rk[i-1]]\geq 2\) 时:

\(sa[rk[i-1]-1]=k\),则有 \(LCP(i-1,k)\geq 2\)

同时去掉后缀 \(i-1\) 和后缀 \(k\) 的第一个字符,得到后缀 \(i\) 和后缀 \(k+1\)

此时有 \(s[i,n]<s[k+1,n],LCP(i,k+1)=LCP(i-1,k)-1\)

\(height\) 的 LCP 最大性,\(height[i]\) 至少为 \(LCP(i,k+1)\),也就是 \(height[rk[i-1]]-1\)

任意两个后缀的 LCP

对于一棵树 \(T\),我们拿出树上一个点数 \(\geq 2\) 的点集 \(S\)

\(x,y\) 分别为 \(S\)\(dfn\) 序最大、最小的点。有 \(\max_{i\in S,j\in S,i\neq j}\{dep[LCA(i,j)]\}=dep[LCA(x,y)]\)

对于两个后缀 \(i,j\),不妨设\(rk[i]<rk[j]\)。根据上面的结论,\(LCP(i,j)=\min_{rk[i]< k\leq rk[j]}\{height[k]\}\)

任意两个子串的 LCP

子串是后缀的前缀。

\(x=s[i,j],y=s[l,r]\)\(LCP(x,y)=\min\{|x|,|y|,LCP(s[i,n],s[l,n])\}\)

同样可以判断 \(x,y\) 的字典序大小。若 \(rk[i]<rk[l]\lor(rk[i]=rk[l]\land |x|<|y|)\),则 \(x<y\)

不同子串个数

将所有后缀插入到 Trie 树 \(T\) 中,答案即为 \(T\) 的节点个数。

按照字典序从小到大插入每个后缀 \(x\),设 \(x\) 前面一名的后缀为 \(y\)。新增的点即为 \(|x|-LCP(x,y)\)

于是答案为 \(\dfrac {n(n+1)} 2-\sum\limits_{i=2}^n height[i]\)

出现至少 \(k\) 次的子串的最大长度

子串 \(x\)\(s\) 中出现 \(k\) 次,等价于 \(x\) 至少是 \(k\) 个后缀的前缀,又等价于 \(x\)\(sa\) 中是至少连续 \(k\) 和后缀的前缀。

于是求出 \(height\) 后,取连续 \(k-1\) 个元素的最小值的最大值即可。

posted @ 2025-06-27 19:46  XP3301_Pipi  阅读(12)  评论(0)    收藏  举报
Title