RMQ問題與LCA問題

2021-05-21 22:59:52 字數 2123 閱讀 4416

一、區間最小/ 最大查詢(range minimum/maximum query) :rmq 問題

//toj: 2762

[ 描述] 已知長度為l 的數列a ,詢問區間[l, r] 中的最值。

若詢問的次數較少,可以用線性的複雜度來查詢,但如果詢問的次數過多且l 過大,那麼複雜度就會很高。所以需要更快速的查詢方法。

st 演算法:預處理o(nlogn) ,查詢指定區間的最值o(1)

把待求區間[l, r] 分為兩段長為len 的區間,左邊一段為[l, l+len-1] ,右邊一段為[r-len+1, r] ,len 必須使得兩段區間覆蓋待求區間。

設所求陣列為w :

那麼,所求最小值就是兩個區間的最小值的最小值:

即min(min, min)

若都在預先處理中先求得兩個區間的最小值,則每次查詢的複雜度都是o(1) 。

預處理:(dp )

設dp[i][j] 表示從第i 個數起連續2^j 個數中的最值。

dp[i][0]=a[i] 1<=i<=n

dp[i][j]=min(dp[i][j-1], dp[i+2^(j-i)][j-1])

求最值:把區間[l, r] 分成兩個長度為2^n 的區間。

為使區間被分解後,長度為2^n ,區間部分可重疊,但不可越過[l, r] 。

例如 [3, 9] à [3, 6]+[6, 9] 即:dp[3, 2] 和dp[6, 2]

注:dmin 與dmax 用前清零。

將rmq 拓展到二維狀況時,依然使用st 演算法先進行預處理,再進行查詢。其中可以有兩種做法(以取最大值為例),對於數字矩陣num[1..m][1..n] ,取其中乙個子矩陣的最大值。第一種方法:dmax[x][y][i][j] 表示對於點(x, y) 為左上點,(x+2^i-1, y+2^j-1) 為右下點的子矩陣的最大值。在詢問時,將待查詢矩陣一分為四取最大值即可。

//toj: 3375

第二種方法:是dmax[x][y][i] 記錄以(x, y) 為左上點,(x+2^i-1, y+2^i-1) 為右下點的正子矩陣的最大值。在詢問時,也需要將待查詢矩陣分為若干正子矩陣,取最大值即可。

第二種方法由於比第一種方法在dmax 上少了乙個維度,所以大大的節省了空間。

一、 最近公共祖先( lowest common ancestors ) :lca 問題

//toj: 3361 1051

對於有根樹t 的兩個結點u 、v ,最近公共祖先lca(t, u, v) 表示乙個結點x ,滿足x 是u 、v 的祖先且x 的深度盡可能大。另一種理解方式是把t 理解為乙個無向無環圖,而lca(t, u, v) 即u 到v 的最短路上深度最小的點。

解決lca 主要是用最經典的tarjan 離線演算法,需要用到並查集來輔助。

1 、在並查集中建立僅包含x 結點的集合,即fa[x]=x;

2 、處理x 的所有孩子,處理完每個孩子後,令fa[ 孩子]=x ,即將孩子和x 所在集合合併;

3 、全部孩子處理完後,將x 標記為處理結束;

4 、處理所有與x 相關的詢問。對於每個詢問lca(x, y) ,若y 已被標記,則記錄下lca(x, y)=find(y) ,即y 所在集合的代表元素。

[ 模板] ( 以3361 為例)

在處理詢問的時候需要建立關聯序列表,另外呼叫lca 時候必須呼叫根結點。

在查詢的時候根據題意修改。

二、 lca 與rmq :

// 資料:rmq 與lca 問題( 郭華陽).ppt

rmq 向lca 轉化:設序列a 的長度為n

1 、設序列中最小值為為ak ,建立優先順序為ak 的根結點tk ;

2 、將a[1..k-1] 遞迴建樹作為tk 的左子樹;

3 、將a[k+1..n] 遞迴建樹作為tk 的右子樹。

rmq(a, i, j) 查詢a[i..j] 的最值即為lca(t, i, j) 。

lca 向rmq 轉化:

對有根樹t 進行dfs ,將遍歷到的結點按照順序記下,得到乙個長度為2*n-1 的序列,稱之為t 的尤拉序列f ,每個結點在尤拉序列中出現,記錄pos[u] 為結點u 在尤拉序列中

第一次出現的位置。

lca(t, u, v)=rmq(b, pos(u), pos(v))

演算法之LCA與RMQ問題

1 概述 lca least common ancestors 即最近公共祖先,是指這樣乙個問題 在有根樹中,找出某兩個結點u和v最近的公共祖先 另一種說法,離樹根最遠的公共祖先 rmq range minimum maximum query 即區間最值查詢,是指這樣乙個問題 對於長度為n的數列a,...

LCA和RMQ問題雜談

首先 mathrm 問題指的是求解樹上兩點的最近公共祖先,mathrm 問題指的是求解數列區間最值。mathrm 問題轉 mathrm 問題應該是人盡皆知了,我們可以先跑出樹的 mathrm 序,使用每次進入或回到節點都記錄一次的那種 mathrm 序,那麼只需記錄每個節點第一次出現位置就可以查詢了...

LCA問題的RMQ解法解析

lca問題是指最近公共祖先問題,rmq問題是只區間最小值問題,我們可以將lca問題轉化為rmq問題,然後利用rmq的解法來解決lca問題。有關rmq問題的詳解可以參考我的部落格,有關於rmq問題的詳解。本部落格重點講如何將lca問題轉化為rmq問題。當我們深度遍歷樹時,我們沒遇到乙個未訪問過的節點就...