算法学习:后缀数组 height的求取
【前置知識】
? 后綴數組
?
?
【定義】
【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 { LCP ( k - 1 , k ), i + 1 <= k <= j }
? 可利用此項用 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)
{
int k = 0;
for (int i = 1; i <= n; i++)
{
if (k) k--;
int j = SA[rak[i] - 1];
while (i+k<=n && j+k<=n &&s[i + k] == s[j + k]) k++;
height[rak[i]] = k;
}
}
?
?
?
題目:
?
【SDOI 2008】 Sandy的卡片
?
?
?
??
?
轉載于:https://www.cnblogs.com/rentu/p/11338901.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的算法学习:后缀数组 height的求取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue 上传图片 input=file
- 下一篇: 【SDOI2008】Sandy的卡片(后