后缀数组的应用
后缀数组的应用
记 “后缀 \(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\) 个元素的最小值的最大值即可。

浙公网安备 33010602011771号