poj2104 劃分樹問題

2021-07-24 01:11:45 字數 1249 閱讀 6469

這個題目的意思是給你乙個區間,讓你找到在某個給出的子區間當中第k大的數。

這是我的第乙個劃分樹題目,因為之前做了好多線段樹的題目了,看了看書上基本的**,然後按照自己的思路寫了出來。

按照這個題目的思路,得用到二分,把給出的元素x[n]排好序y[n],對於乙個給出的子區間,那麼第k大的元素應該滿足兩點:

(1)在區間當中至少存在k個不超過第k大的元素

(2)在區間當中小於第k大的元素不到k個

從排好序列的區間當中取出mid,劃分樹當中每個節點儲存的是乙個區間內排好序的元素,當這個節點所在的區間完全包含在被給出的區間的時候,就找出小於等於y[mid]的元素的個數,每次查詢完成以後得出小於等於y[mid]的元素的個數t,如果t>=k,就讓right=mid,否則的話就讓left=mid;這樣二分可以很快找到滿足條件的y[mid],最後輸出的y[mid]就是查詢到的區間當中的第k大的數

#include #include #include #include #define tag 1200

#define maxn 100010

using namespace std;

int x[maxn];

int y[maxn];

vectorve[4*maxn];

void build(int now,int l,int r)

int mid=(l+r)>>1;

build(2*now,l,mid);

build(2*now+1,mid+1,r);

ve[now].resize(r-l+1);//目的是申請足夠容納[l,r]內元素的記憶體單元

merge(ve[2*now].begin(),ve[2*now].end(),ve[2*now+1].begin(),ve[2*now+1].end(),ve[now].begin());//由下往上區間合併,合併的同時完成了排序

}int query(int now,int l,int r,int tl,int tr,int val)//查詢操作,關鍵地方

else

}int main()

; while(cin>>n>>m)

sort(y+1,y+1+n);

build(1,1,n);

int l,r,val,mid;

int sum;

while(m--)

else

}printf("%d\n",y[right]);}}

return 0;

}

劃分樹學習 poj 2104

開始學習劃分樹 按照網上的題目大概敲了下 還有些不懂的地方 尤其是查詢 還不是很懂 下次在看懂 下面是這題的 include include includeusing namespace std int const tcnt 100100 struct node tree tcnt 4 int a ...

主席樹模板 POJ2104

離散化 對陣列排完序後用unique去重,unique返回的是去重後的陣列的末位址,減去第乙個元素的位址就能得到去重後的陣列大小,用lower bound查詢原數字在排序去重後的序列中的位序,用位序代替數字完成離散化。include include using namespace std defin...

主席樹模板(poj2104)

主席樹是可持久化線段樹,可以記錄線段樹的歷史版本。中和線段樹不同的是,l,r記錄的是左右子樹編號,因為普通的線段樹版本中,左右子樹自然就是o 1和o 1 1,但是主席樹中並不保證這個特性,所以需要記錄一下。是 include include include include include using...