I recently learned wavelet trees. This data structure can handle the following types of range queries in logarithmic time:
- Number of elements in subarray A[L...R] that are less than or equal to y.
- Number of occurrences of element x in subarray A[L...R].
- The kth smallest element in subarray A[L...R].
But I couldn't find the array based implementation of it anywhere, and as I don't like pointers(also pointer based implementations are often slower than array based ones because of the dynamic memory allocation), I implemented it myself. Here is the implementation: https://github.com/thisIsMorningstar/Competitive_Programming/blob/main/templates/wavelet_tree.cpp
I stress tested this with a bruteforce code against a couple thousand random testcases and it passed. But if you find any bugs in it, do let me know :).
You can learn about wavelet trees from here: https://mirror.codeforces.com/blog/entry/52854
Great job man :D
:)
Second type of query is just subset of the first type.
Is it because equal(x) = less_than_or_equal(x) — less_than_or_equal(x-1)?
Yes, exactly.
I don't like pointers
Proceeds to use l and r array the exact same way as pointers...
how is it exactly like pointers? ;-;
You're using a well-known technique, which is not specific to wavelet tree. Instead of using dynamic allocation like
You use indices on a big pre-allocated array (or deque) :
But observe that
preallocated[leftId]
is equivalent to*(preallocated + leftId)
i.e.leftPtr = preallocated + leftId
.You are basically using pointers but in a specific, pre-allocated memory block. It is indeed a good optimization but the idea is not really different (I would say that you "optimized" the pointers, you didn't get rid of them).
I don't know why downvoted. Exactly what I meant.