劃分樹 求區間K大數

2021-09-30 05:01:09 字數 627 閱讀 8288

求區間k大數,眾所周知有二分答案+樹套樹的做法,每個詢問複雜度為o(log3n),可謂近似乙個o(n)了,不僅時間複雜度高,程式設計複雜度也不低,後來才發現還有一種叫劃分樹的資料結構,專門做這種問題。

本來覺得知道個樹套樹就夠了,據我所知劃分樹還不支援區間修改操作,但是這次noi一試的piano偏偏那出題人就有這麼重口味,給你來兩個500000的點!真是不簡單,當時我都在想有沒有o(n)的演算法了。樹套樹的複雜度偏偏就被卡掉了,三個點平均每個點要跑5秒,好吧,那就學學劃分樹把。

看了劃分樹以後覺得是繼字尾陣列以來第二巧妙的資料結構,劃分樹中的節點代表的區間並不是原陣列的區間,而是在排序以後陣列的區間,通過分治的思想解決問題。

剛開始看劃分樹還覺得比較飄,對於每乙個區間中的每乙個節點,要記錄乙個從這個節點到這個節點所在的區間的左端點之間有多少個進入了左子樹(這個區間中前mid小的數進入左子樹,其他右子樹),這個值很關鍵,我就可以o(1)的知道我所查詢的區間的數是在左子樹還是在右子樹了。

建樹很好寫,主要是查詢的式子比較長,下面簡略的寫下:

(rs是區間左端點到我要查詢的右端點之間進入左子樹的個數,ls是區間左端點到我要查詢的區間左端點之間進入左子樹的個數,因此我就可以知道我要查詢的區間有多少進入左子樹的,從而知道我是要遞迴進左子樹查詢還是遞迴進右子樹查詢)

靜態區間第k大(劃分樹)

poj 2104為例 經典劃分樹問題 思想 利用快速排序思想,include include using namespace std const int maxn 100010 int tree 20 maxn 每層每個位置的值 int sorted maxn 排好序的陣列,方便尋找中值 int l...

區間K大數

區間k大數 問題描述 給定乙個序列,每次詢問序列中第 l個數到第 r個數中第 k大的數是哪個。輸入格式 第一行包含乙個數 n,表示序列長度。第二行包含 n個正整數,表示給定的序列。第三個包含乙個正整數 m,表示詢問個數。接下來m行,每行三個數 l,r,k 表示詢問序列從左往右第 l個數到第 r個數中...

快樂找到區間第K大 劃分樹

劃分樹,顧名思義就是將乙個序列,劃分成很多小部分。其作用就是可以快樂地找到給定區間第k大的數。其實使用歸併樹和快排也都可以找到區間內第k大的數,但其效率都不如劃分樹要好,快排過的時間複雜度o n x m 而劃分樹是o n x logn 劃分樹原理 1.建樹 根結點就是原序列,左孩子儲存父結點所有元素...