Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
merge_sort_tree.hpp
[詳解]
1#include"../../kyopro_library/template.hpp"
2
3/// @brief マージソート木
4template<typename T>
6 MergeSortTree()=default;
7
8 /// @brief 配列 v からマージソート木を構築する
9 MergeSortTree(const vector<T>& v) {
10 n=v.size();
11 mx=*max_element(ALL(v)),mn=*min_element(ALL(v));
12 dat=vector<vector<T>>(n<<1);
13 for(int i=0; i<n; i++) dat[n+i]={v[i]};
14 for(int i=n-1; i>0; i--) {
15 merge(ALL(dat[i<<1]),ALL(dat[i<<1|1]),back_inserter(dat[i]));
16 }
17 }
18
19 /// @brief 区間 [l, r) に存在する val 未満の値の個数を返す
20 /// @note O(log(N)^2)
21 int count_lt(int l, int r, T val) {
22 l+=n,r+=n;
23 int ret=0;
24 while(l<r) {
25 if(l&1) ret+=LB(dat[l],val),l++;
26 if(r&1) --r,ret+=LB(dat[r],val);
27 l>>=1,r>>=1;
28 }
29 return ret;
30 }
31
32 /// @brief 区間 [l, r) に存在する val 以下の値の個数を返す
33 /// @note O(log(N)^2)
34 int count_le(int l, int r, T val) {
35 return count_lt(l,r,val+1);
36 }
37
38 /// @brief 区間 [l, r) に存在する val より大きい値の個数を返す
39 /// @note O(log(N)^2)
40 int count_gt(int l, int r, T val) {
41 return r-l-count_le(l,r,val);
42 }
43
44 /// @brief 区間 [l, r) に存在する val 以上の値の個数を返す
45 /// @note O(log(N)^2)
46 int count_ge(int l, int r, T val) {
47 return r-l-count_lt(l,r,val);
48 }
49
50 /// @brief 区間 [l, r) の小さい方から k(1-indexed) 番目の値を返す
51 /// @note O(log(N)^3)
52 T kth(int l, int r, int k) {
53 T lo=mn-1,hi=mx+1;
54 while(hi-lo>1) {
55 T mid=(hi+lo)/2;
56 if(count_lt(l,r,mid)>=k) hi=mid;
57 else lo=mid;
58 }
59 return lo;
60 }
61
62private:
63 int n;
64 vector<vector<T>> dat;
65 T mx,mn;
66};
マージソート木
MergeSortTree()=default
int count_lt(int l, int r, T val)
区間 [l, r) に存在する val 未満の値の個数を返す
int count_le(int l, int r, T val)
区間 [l, r) に存在する val 以下の値の個数を返す
int count_gt(int l, int r, T val)
区間 [l, r) に存在する val より大きい値の個数を返す
T kth(int l, int r, int k)
区間 [l, r) の小さい方から k(1-indexed) 番目の値を返す
int count_ge(int l, int r, T val)
区間 [l, r) に存在する val 以上の値の個数を返す
MergeSortTree(const vector< T > &v)
配列 v からマージソート木を構築する
#define ALL(x)
Definition template.hpp:4