后缀数组学习笔记 ----height引理的证明

\(lcp(i,j)\) 表示 后缀 \(i\) 和后缀 \(j\) 的最长公共前缀的长度

\(height[i] = lcp(sa[i],sa[i-1])\) 表示第 \(i\) 名的后缀与它前一名的后缀的最长公共长度

\(height[1] = 0\)

引理:\(heigh[rk[i]]>=height[rk[i-1]]-1\)

证明如下:

当: \(height[rk[i-1]]<=1\) 时,上式子显然成立

当:\(height[rk[i-1]]>1\) 时:

  • 设后缀 \(i-1\)\(aAD\)\(A\) 是一个长度为 \(height[rk[i-1]]-1\) 的字符串),那么后缀 \(i\)\(AD\)
  • 设后缀 \(sa[rk[i-1]-1]\)\(aAB\) (\(B\)<\(D\)) ,那么\(height[rk[i-1]] = lcp(i-1,sa[rk[i-1]-1]) = aA\)
  • 因为 \(sa[rk[i-1]-1]+1 = AB\) ,而后缀 \(i\)\(AD\) ,所以 \(sa[rk[i-1]-1]+1\) 一定在 \(i\) 的前面。
  • \(r = rk[i],l = rk[sa[rk[i-1]-1]+1]\) ,那么 \(l<=rk[i]-1<r\) ,因为 \(l,r\) 都含有 \(A\),所以 \(rk[i]-1\) 一定含有 \(A\), 所以 \(rk[i]-1 = A[C|D]\)
  • 所以 \(lcp(i,sa[rk[i]-1]):AX\) \(X\) 可能为空
//求height数组,因为k最多减n次,最多加2*n次,所以复杂度是 O(n)
for(int i=1,k=0;i<=n;i++){
    if(k) k--;
    while(s[i+k]==s[sa[rk[i]-1]+k]) ++k;
    height[rk[i]] = k;
}
posted @ 2021-02-14 16:39  EchoZQN  阅读(83)  评论(0编辑  收藏  举报