Count smaller elements on right side
input :[4,12,5,6,1,34,3,2] output: [3,5,3,3,0,2,1,0]
I know this can be solved using MergeSort but i want to know how to solve it using segment tree ? What actually we have to store in Node of segment tree.
# | User | Rating |
---|---|---|
1 | tourist | 3985 |
2 | jiangly | 3814 |
3 | jqdai0815 | 3682 |
4 | Benq | 3529 |
5 | orzdevinwang | 3526 |
6 | ksun48 | 3517 |
7 | Radewoosh | 3410 |
8 | hos.lyric | 3399 |
9 | ecnerwala | 3392 |
9 | Um_nik | 3392 |
# | User | Contrib. |
---|---|---|
1 | cry | 169 |
2 | maomao90 | 162 |
2 | Um_nik | 162 |
4 | atcoder_official | 160 |
5 | djm03178 | 158 |
6 | -is-this-fft- | 157 |
7 | adamant | 155 |
8 | Dominater069 | 154 |
8 | awoo | 154 |
10 | luogu_official | 150 |
Count smaller elements on right side
input :[4,12,5,6,1,34,3,2] output: [3,5,3,3,0,2,1,0]
I know this can be solved using MergeSort but i want to know how to solve it using segment tree ? What actually we have to store in Node of segment tree.
Name |
---|
Please give me idea ?
store numbers in pair of (value, index) then sort them. then start from the smaller one and for each one count number of element in array that you have visit them (they have smaller value) and their index is bigger than this one. then add 1 to index of this one in segment tree.
I hope this could help you and sorry for my poor English :)
start from the right, when we encounter element x, the answer is query from [0..x-1], then update the segment tree by increasing value on index x by 1 on the segment tree.
this is similar to counting sort, if the maximum element is too large, just compress the data first.
Right :) got. Thanks :) What so you mean compress data first ?
If values are big enough (up to 10^9 or even 10^18) you can't usually just create RSQ structure. You should make numbers smaller without changing its order. For example [5,7,5,100000] -> [0,1,0,2]
And How it is coming ? [5,7,5,100000] -> [0,1,0,2] ?
basically change the value of the smallest number in the current data to 0, 2nd smallest to 1, 3rd smallest to 2, etc
zeulb explains the idea what to do. I'd recommend you to think how to do that yourself. It could be easily done in
nlogn
. Hints:You may use
std::set
/java.util.TreeSet or sort,unique and binary search. (The second is faster)You can use Binary Indexed Tree. Here is a code.
void update(int i) { for(; i < maxNumber; i += i&-i) BIT[i]++; }
int find(int i) { int res(0); for(; i; i -= i&-i) res += BIT[i]; return res; }
void solve() { read(A); for(i = N; i >= 1; i--) { r[i] = find(A[i]); update(A[i]); } } You can update BIT( Binary Indexed Tree ) int O(logN) and get the result in O(logN). Then complexity is O(NlogN) but it is faster than segment tree and you can implement this easier.
We can solve this problem by using BIT and Segment Tree (of course). The condination is the values must be smaller than 10000000 and strictly larger than 0 (if not, you can compress your array by replace value of array with rank of it in array, for example, [500,700,500,850] -> [1,2,1,3]). In our segment tree, node k whick manage segment [l,r] will contains sum of elements from l to r. Let i run from n down to 1, with i, we assign result[i] := segmenttree.get(1,a[i]-1), then call segmenttree.set(a[i], 1) (increase element a[i]-th in tree by 1). Lastly, we print array result[].
This is pseudo code which I hope it can help you:
It is easier when you use Binary Indexed Tree.