RMQ LCA
第一節?RMQ、LCA概述
? ? ? LCA:Lowest?Common?Ancestor,譯為最近公共祖先。其解釋就是說:在有根樹中,找出樹中任意兩個節點最近的公共祖先,或者說找到任意兩個節點離樹根最遠的公共祖先。
? ? ? ?RMQ:Range?Minimum?Query,譯為區間最小值查詢。其解釋就是說:對于含有N個元素的數列A,在數列中找到兩個指定索引之間的最小值及最小值的位置。
第二節?RMQ Algorithm
? ?首先我們來看RQM算法,我將會根據預處理和查詢的速度介紹幾種解決該問題的方法。
? 設有數組A[N],其表示如下:
?要求求得區間(2,7)的最小元素,如下圖所示:
解法一:Sparse?Table(ST)?algorithm
? ? ?ST算法是一種比較高效的在線處理RMQ問題的算法,所謂在線算法,是指每輸入一個查詢就會馬上處理這個查詢。ST算法首先會對序列做預處理,完成之后就可以對查詢做回答了。
? ? 分析:
? ? ? ? ? ? 預處理:O(N * LogN)。
? ? ? ? ? ? 查詢:O(1),這樣的查詢正是我們想要的。
? 算法流程:
預處理:首先用維護一個數組M[N][LogN],M[i][j]的值是從原序列A的i位置開始,連續2j?個元素的最小值的下標,如下所示:
? ? ? ? ? ?
?那么,我們如何計算M[i][j]呢?
? ??我們采用DP的思想將區間分成兩部分,即M[i][j?-?1]和M[i][2^(j?-?1)]?,F在我們只需比較這兩個子區間就可以得到M[i][j]了。比較規則如下:
? ? ? ? ? ? ? ? ? ? ?
?于是乎,就可按照此寫出代碼:
void Proprocessing(int M[N][logN], int *A, int N){int i, j;for(j = 1; (1 << j) < N; j++){for(i = 0; (i + (1 << j) - 1) < N; i++){if(A[ M[i][j - 1] ] < A[ M[i + (1 << (j - 1))][i - 1]]){M[i][j] = M[i][j - 1];}else{M[i][j] = A[ M[i + (1 << (j - 1))][i - 1]];}}} }?????
https://blog.csdn.net/fengchaokobe/article/details/8104784#
??? ? ?https://blog.csdn.net/blaze003003/article/details/81084954
總結
- 上一篇: 牛顿迭代法(Newton's Metho
- 下一篇: POJ2536、3370