題意: 給出乙個區間[l,r]和乙個k,要查詢 a(l),a(l+1), … a(r)中,按公升序排列下第k個數。
例如數列:1 5 2 6 3 7 4
要查詢[2, 5]中第 3個數, 即 5 2 6 3 按公升序排列 2 3 5 6的第 3個, 即為5。
很樸素的想法就是每次查詢的時候都把要查詢的區間排個序,然後取出第k個,但這種做法時間複雜度太高(因為查詢次數高達5000次)。最壞情況下m *n *logn。
另一種做法便是採用二分加上線段樹的做法, 要求公升序排列中第k個數,換一句話說就是要找到乙個x,使其在此排列中有k-1個不超過x的數。首先查詢x這個使用二分即可,那線段樹有何作用呢?
由線段樹的性質可知,每個結點表示乙個區間,若每個區間都是有序的,那我們查詢乙個區間的時候便可以把它分解成若干個區間,在每乙個區間中查詢不超過x的數,最後累加起來,若個數超過k,則說明取得這個x太大,需要再小一點,若< k,則需再大一點,若=k,不一定是最優的,可能還可以更小。
再線段樹上如何快速求得不超過x的個數是關鍵,這裡可以採用在合併子節點的時候排序,使得線段樹每個區間都有序(類似於歸併排序)。這樣在查詢的時候便可以直接使用二分搜尋找下界即可。
時間複雜度為o(nlogn+mlog^3 n) ,nlogn為建樹的時間。
POJ2104 平方分割)
解題思路 以前使用主席樹ac過一次的題目,現在用平方分割來試試。大致做法就是,把所有數放進maxn大小的桶中。然後對各個桶中的數進行排序。處理時採用二分搜尋的辦法確定結果。即如果有1.n個數。則用二分來試這個數試mid是區間中第幾小的數。關於平方分割處理的細節就是 把不完全包括在桶中部分用列舉的辦法...
poj2104 劃分樹問題
這個題目的意思是給你乙個區間,讓你找到在某個給出的子區間當中第k大的數。這是我的第乙個劃分樹題目,因為之前做了好多線段樹的題目了,看了看書上基本的 然後按照自己的思路寫了出來。按照這個題目的思路,得用到二分,把給出的元素x n 排好序y n 對於乙個給出的子區間,那麼第k大的元素應該滿足兩點 1 在...
POJ2104 主席樹 整體二分
題目鏈結 kth number 主 席樹 主席樹主席 樹主席樹模板題 關於主席樹沒啥好講的,其實就是動態開點 線段樹 pragma gcc optimize 2 include include include using namespace std typedef long long ll cons...