學習筆記 字尾陣列 1

2022-06-02 03:06:07 字數 2320 閱讀 6576

全文1820詞,預計閱讀時間5min

目錄例題

字尾陣列是處理字串的有力工具,常在比賽中用到。本文主要介紹字尾陣列的概念與部分例題。

關於部分例題,我們將在後續文章介紹。

那麼,我們可以先按第二關鍵字排序,此時序列是按照第二關鍵字從小到大排列的。我們再從左到右,按第一關鍵字排序。這樣就可以使得其有序。這就是基數排序基數排序是穩定的

舉個栗子:

(1,6)(1,5)(2,3)(3,4)(8,5)(16,43)(2,20)(4,28)

按第二關鍵字排序後

(2,3)(3,4)(1,5)(8,5)(1,6)(2,20)(4,28)(16,43)

按第一關鍵字排序後

(1,5)(1,6)(2,3)(2,20)(3,4)(4,28)(8,5)(16,43)

此時序列有序

關於字尾陣列的構造,有倍增與\(dc3\)兩種演算法。倍增演算法較為簡單,本文主要介紹倍增演算法。

注:倍增演算法\(o(nlogn)\),\(dc3\)演算法\(o(n)\),\(n\)為字串長度

我們可以對從每個字元開始,長度為\(2^i​\)的字串進行排序(當字串長度不足時,根據上文定義,在後面補比所有出現過字元還要小的字元)。當到達\(len_t\le 2^i​\),顯然所有字串的排名會變得不重複。並且當長度為\(2^i​\)的字串排名不重複時,長度為\(2^​\)的字串排名也不重複。

當我們知道長度為\(2^i​\)的排名時,如何求出長度為\(2^​\)的排名呢?我們知道\(2 \times 2^i=2^​\),與上文的基數排序對比,想出怎麼做了嗎?

其實,我們可以直接用\(2^i​\)的排名搞。如下圖所示,以前半段的排名為第一關鍵字,以後半段的排名作為第二關鍵字,做基數排序,就可以知道新的排名了

所以,我們只用在字串中求出長度為\(2^0=1​\)的排名,後面的排名都可以通過基數排序求出。

我們的程式基本成形了,步驟如下:

1.求出長度為\(2^0​\)的排名

2.基數排序,由\(2^i\)的排名求出\(2^\)的排名

3.處理每個字尾的排名

不過這裡還要介紹乙個優化:第二關鍵字其實不用排序,我們可以通過以下方法得出順序:

設長度為\(2^i\)

1.長度不到\(2^i\)的字串,按從長到短的順序加入陣列

2.從前往後遍歷\(sa​\),若\(sa_i-2^i \ge 0​\)(字串從0開始),則將其加入陣列

此陣列即為第二關鍵字的排序。

上**(luogu3809)

本題就是求最終的\(sa\)陣列,處理完輸出即可。當然,本題中可以把基數排序換成快排。

#includeusing namespace std;

int rank[1000100],nrank[1000100],sa[1000100],sum[1000100],ans[1000100],n,p[1000100];

string st;

bool the_same(int x,int y,int l)

int main()

-1 (height_ \ge height_}-1​\)

證明

定義\(j​\)是開頭為\(sa_-1}​\)的字串,其\(lcp​\)為\(h_i​\)。

那麼以\(j+1​\)與\(i​\)的\(lcp​\)顯然是\(h_i-1​\)

由上面的定理,得\(j+1​\)至\(i​\)中間的\(height​\)值大於等於\(h_i-1​\)。

顯然,\(rank_i>rank_\),且\(sa_\)在\(j+1\)到\(i-1\)之間。

證畢。所以,\(height_ \ge height_} -1​\)

所以,我們可以按照\(rank​\)順序,求出\(height​\),時間複雜度降為\(o(n)​\)

**如下

void calc_height()

{ int j=0;

for (int i=0;iluogu 2408 不同子串個數

(spoj 694 / 705)

題目鏈結 題意:給出乙個字串,求不同子串的個數

題解:乙個子串一定是乙個字尾的字首,所以我們求出子串個數後,再減去相同子串個數,即每個字尾與排名是其前一位的字尾的\(lcp​\),即為答案。

詳細題解

例題

學習筆記 字尾陣列 1

目錄 全文1820詞,預計閱讀時間5min 字尾陣列是處理字串的有力工具,常在比賽中用到。本文主要介紹字尾陣列的概念與部分例題。關於部分例題,我們將在後續文章介紹。那麼,我們可以先按第二關鍵字排序,此時序列是按照第二關鍵字從小到大排列的。我們再從左到右,按第一關鍵字排序。這樣就可以使得其有序。這就是...

字尾陣列學習筆記

要用好字尾陣列要先理解裡面幾個陣列的概念 sa i 表示字典序第i大的字尾下標 字典序排名依次是1 len stri ng ra nk i 表示下標為i的字尾字典序排名 he ight i 表示sa i 和sa i 1 最長公共字首的長度.乙個性質 lc p su ffix i suff ix j ...

字尾陣列 學習筆記

字尾陣列是處理字串的強有力的工具 在字串處理當中,字尾樹和字尾陣列都是非常有力的工具。其實字尾陣列是字尾樹的乙個非常精巧的替代品,它比字尾樹容易程式設計實現,能夠實現字尾樹的很多功能而時間複雜度也不太遜色,並且,它比字尾樹所占用的空間小很多。可以說,在資訊學競賽中字尾陣列比字尾樹要更為實用。我們定義...