字尾陣列 學習筆記

2021-09-18 02:30:18 字數 2416 閱讀 7716

剛剛學完回文自動機

來學字尾陣列

一開始思路看得懂

但是**看不懂呀……

一堆神仙**

洛谷p3809

勿謂我,何強過者,炸哉!
我們需要一種新的演算法——字尾陣列

首先,輸入字串

scanf

("%s"

, ch+1)

; n=

strlen

(ch+1)

;

然後,按照題意

suffix_sort

(ch)

;for

(int i=

1; i<=n; i++

)printf

("%d "

,sa[i]

);

主程式就是這麼簡單

int

main()

好了,廢話完了,步入正題

inline

void

suffix_sort

(char ch)

sort()

;for

(int w=

1, p=

0; p

}

你一定看不懂。(除非你學過)

對,你要是光給我這些**

我也看不懂

陣列定義

某巨佬曰:

sa[i]:排名為i的字尾的位置

rak[i]:從第i個位置開始的字尾的排名,下文為了敘述方便,把從第i個位置開始的字尾簡稱為字尾i

tp[i]:基數排序的第二關鍵字,意義與sa一樣,即第二關鍵字排名為i的字尾的位置

tax[i]:i號元素出現了多少次。輔助基數排序

q:排名?

a:就是字典序啦……

而且

還有這個性質

rak[sa[i]

]=i;

sa[rak[i]

]=i;

如何排序

拆開每個字尾

你會發現

一開始這個字尾第乙個值就是這個字尾的起始值

第二個值呢?

其實,我們可以把乙個字尾看成乙個二元組

( ch

[i],

i)(ch[i], i)

(ch[i]

,i)這裡的chch

ch就是字串

對這個二元組進行基數排序

你就會感到快樂

你就會得到排名

倍增既然是倍增,要有倍增的樣子

p.s.倍增的樣子?不就是暴力?

我們在進行第一次排序時

求出了排名

但是這排名有重複

也就是有並列

所以我們要向外擴充套件每個字尾

無法擴充套件的,補0

你已經發現

我們第一次時取每個字尾的開頭

那麼,就產生了許多重複名次

所以,我們可以去對比每個字尾的前(1*2=2)個字元

如果還不行

就對比前(2*2=4)個字元

以此類推

直到排名沒有並列為止

思想就是這樣

不難吧但是

你看看**……

基數排序

你肯定會問:那個sort函式去**了?

它在這裡:

inline

void

sort()

這個tax,就是桶

如果你不了解基數排序

還是baidu一下

你會問,什麼叫:

s a[

tax[

rak[

tp[i

]]]−

−]=t

p[i]

;sa[tax[rak[tp[i]]]--]=tp[i];

sa[tax

[rak

[tp[

i]]]

−−]=

tp[i

];t ax

[rak

[tp[

i]]]

tax[rak[tp[i]]]

tax[ra

k[tp

[i]]

]就表示當第一關鍵字相同時,第二關鍵字較大的這個字尾的排名是什麼

於是,字尾陣列就完了。

其實我覺得字尾陣列難在看**

思想還是比較好接受的

自為風月馬前卒

洛谷

字尾陣列學習筆記

要用好字尾陣列要先理解裡面幾個陣列的概念 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 ...

字尾陣列 學習筆記

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

字尾陣列學習筆記

要用好字尾陣列要先理解裡面幾個陣列的概念 sa i 表示字典序第i大的字尾下標 字典序排名依次是1?len string rank i 表示下標為i的字尾字典序排名 height i 表示sa i 和sa i?1 最長公共字首的長度.乙個性質 lcp suffix i suffix j min ra...