演算法學習 字尾陣列 height的求取

2022-07-24 12:00:14 字數 2060 閱讀 3942

【前置知識】

字尾陣列

【定義】

【lcp】全名最長公共字首,兩個字尾之間的最長字首,以下我們定義

lcp ( i , j ) 的意義是字尾 i 和 j 的最長字首

【z函式】函式z [ i ] 表示的是,第 i 個字尾和字串的最長字首

【解決問題】

這兩個演算法都是在解決這個問題

即求字尾和字串和字尾之間的最長公共字首

但是有所不同的是,

字尾陣列最終求出的是,字典序第 i 個字尾和第 i + 1 個字尾的最長公共字首

z函式最終求出的是,第 i 個字尾和字串的最長公共字首

然後通過這個最長公共字首求一些其他的值

【演算法學習】

【字尾陣列】

字尾陣列能夠在 n 的時間內求出字典序第 i 和第 i - 1 個字尾的最長公共字首

而這個函式通常被命名為 height 

height [ i ] 的含義為 ,字典序第 i - 1個字尾和第 i 個字尾的最長公共字首

有以下幾個性質進行求取:(s [ i ] 表示第 i 個字尾)

1.若 i 小於 j , lcp ( i , j )  = min

可利用此項用 rmq 求lcp

2.定義 h [ i ] 為 :第 i 號開始的字尾和他字典序前面的字尾的lcp

即:h [ i ] = height [ rank [ i ] ]

於是有,對於 i > 1 且 rank [ i ]  > 1 有

h [ i ]  >  h [ i - 1 ] - 1 ;

證明如下 :

設 j 為 第 i - 1 號開始的字尾按排名的前面的那個字尾的開始的位置

注意: j 不是第 i - 2號

此時,第 j 個字尾和第 i - 1 個字尾的 lcp 在定義上為 height [ rank [ i - 1 ] ],即 h [ i - 1 ]

即我們要證明的右半部分的一部分

然後我們討論 j + 1 和 i (由得到 i - 1 + 1 ) 的關係:

第一種,當 j 和 i - 1 首字母不相等的情況,h [ i - 1 ] 為 0

那麼顯然  h [ i ] > h [ i - 1 ] - 1

第二種,當 j 和 i - 1 首字母相等的情況,  

那麼顯然,j 和 i - 1 的 lcp 為 h [ i - 1 ] - 1

在字尾中,排名比 i 考前,和字尾 i lcp最長的,相似度最高的顯然是sa中離他最近的那個

即 sa [ rank [ i - 1] ]  - 1 

也就是 , h [ i ] >= h [ i - 1 ] - 1

證畢

所以我們每次找最長字首的時候,都可以從 h [ i - 1 ]  開始檢索

可以模擬 manacher

**如下:

void get_height(char *s)

}題目:

【sdoi 2008】 sandy的卡片

演算法學習 字尾陣列

乙個字串的題,有姿勢水平的oiers的腦中應該要浮現出許多演算法 但是我沒有姿勢,也沒有水平,除了kmp和trie樹,什麼也想不起來。直到我學了它 字尾陣列!多虧這玩意兒,我現在什麼都想不起來了。字尾陣列幹嘛用的?主要處理同乙個字串中的重複子串問題。如何實現?注意到每乙個子串,都是乙個字尾的某個字首...

演算法學習 字尾陣列(SA)

參考部落格 定義 字尾 從第i位到字串結尾的子串 解決問題 從而解決 在字串中找子串 比較子串關係 查詢不同子串的數目 一般來說都是解決 字串和子串關係的問題 演算法學習 字尾陣列能夠在 nlogn的時間複雜度內求取出以下陣列 注意 明白字串包含字元的範圍 sa 儲存,第 i 個數字表示的是字典序第...

關於字尾陣列的倍增演算法和height陣列

自己看著大牛的 學了一下字尾陣列,看了好久好久,想了好久好久才懂了一點點皮毛tat 然後就去刷傳說中的字尾陣列神題,poj3693是進化版的,需要那個相同情況下字典序最小,搞這個搞了超久的說。先簡單說一下字尾陣列。首先有幾個重要的陣列 sa陣列 字尾陣列 儲存所有字尾排序後從小到大的序列。即sa i...