zoukankan      html  css  js  c++  java
  • 后缀数组

    后缀数组

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

    构造 - 倍增法

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

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

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

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

    排序过程采用基数排序,则总复杂度为(O(nlog 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)=sumlimits_{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))),则我们显然有(pge 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]),故(ple 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{egin{array}{**lr**} h[i-1]-1=lcp(s[k+1,n], s[i,n])\ rk[k+1]<rk[i] end{array} ight.)(这一步相当于把他们的首字符砍掉)。

    结合(LCP-Lemma),可得

    [egin{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}\ herefore lcp(s[k+1,n], s[i,n])le LCP(rk[i]-1, rk[i])\ 即h[i-1]-1le h[i],证毕。 ]

  • 相关阅读:
    1242 斐波那契数列的第N项
    1256 乘法逆元
    1264 线段相交
    1265 四点共面
    Uva10881 Piotr's Ants
    hdu 5438 Ponds 长春网赛1002
    CodeForces 540D Bad Luck Island 概率dp
    hdu 1281 二分图残量增广
    hdu 2444判定二分图+最大匹配
    hdu 3416 Marriage Match IV
  • 原文地址:https://www.cnblogs.com/skiceanAKacniu/p/13166341.html
Copyright © 2011-2022 走看看