問題描述
給定m及n個數(1輸出每m個數中的最大數,即1m中的最大數,2m+1中的最大數……,n-m+1~n中的最大數,共n-m+1個。
陣列
將讀入的資料放到乙個線性表f陣列中,然後列舉開始點i,遍歷求出區間[i,i+m-1]中最大值。
堆
將資料組織成樹型結構,即將讀入的數值設計成乙個大根堆,則堆頂元素就是全域性最大值,記錄下每個數值在輸入時的位置。
由於本題是求乙個指定區間的最大值,還需要判斷一下堆頂元素是否位於指定區間,如果在,則直接輸出堆頂元素的值,否則踢掉堆頂元素。
單調佇列
用f(i)代表第i個數對應的答案,a[i]表示第i個數。
於是維護這樣乙個佇列:佇列中的每個元素有兩個域,分別代表他在原佇列中的位置和值,我們隨時保持這個佇列中的元素position域單調遞增,value域單調遞減,。
則在計算f(i)的時候,先將a[i]加入到佇列中。
我們讓a[i]與隊尾元素的value域進行比較,但凡發現小於a[i]的,一律從佇列中踢掉。
由於i-m+1是隨著i單調遞增的,所以對於任意j通過「踢資料」的操作,我們有效地降低了需要維護的資料量。
對比堆的操作中,這些無效的資料仍放在堆中,在加資料的操作時,無疑增加了操作的次數。
採用這種方法,每個資料進出佇列都只有一次,所以時間複雜度為\(o(n)\),而堆的時間複雜度為\(o(nlog_n)\)。
接下來我們需要在隊首不斷刪除,直到隊首的position大於等於i-m+1,此時隊首的value必定是f(i)的結果,因為佇列是單調的。
st表
線段樹
並非原創,僅是整理,請見諒
區間最值問題
實驗任務 已知乙個有 n 個數序列 a i 在序列 a 中的區間 l,r 中的最小值為 a p 求 a p a l a l 1 a r 的最大值為多少?資料輸入 第一行是乙個整數 n 第二行為 n 個整數對應 a i 對於 50 資料 1 n 5000 對於 100 資料 1 n 100 000 1...
RMQ(區間最值問題)
1 概述 lca least common ancestors 即最近公共祖先,是指這樣乙個問題 在有根樹中,找出某兩個結點u和v最近的公共祖先 另一種說法,離樹根最遠的公共祖先 rmq range minimum maximum query 即區間最值查詢,是指這樣乙個問題 對於長度為n的數列a,...
RMQ問題(區間最值查詢)
有一類問題被稱作區間最值問題,描述的是,給定 n 個元素,需要查詢下標位於 p q 之間的最大 小值。首先確定,針對每一次查詢,肯定是不能動態求最值的,因為每次都要計算,可能造成比較多的時間耗費。有 一種比較好的解決辦法是,先得到所有結果,在查詢時直接取出結果。這樣,就需要一種資料結構,能夠覆蓋所有...