Hostek's blog

By Hostek, 19 months ago, In English

Hey, I want to solve this problem: Given array a of length n handle these queries (each query in O(logn))

-> l r k (input) which means output the sum of k largest numbers on segment [l,r] in array a.

($$$n \lt = 10^6$$$ , $$$q \lt = 10^6$$$ (q is number of queries), the array has only positive integers ($$$a_i \lt = 10^9$$$))

I know it is possible to do using Wavelet tree.

  • Vote: I like it
  • 0
  • Vote: I do not like it

»
19 months ago, hide # |
 
Vote: I like it +29 Vote: I do not like it

You can do it using presistent segment tree.

  • »
    »
    18 months ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    Hey, thanks for the reply! Could you provide me implementation of this? Because I think that with persistent segment tree to achieve $$$O(logn)$$$ per query we need to do some tricky binary search?

»
19 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

I don't see how it's possible to solve it faster than $$$O(\log^2 n)$$$ with wavelet tree. Are you sure it's doable?

»
18 months ago, hide # |
 
Vote: I like it +3 Vote: I do not like it

I assume you already know how to range query the $$$k^{th}$$$ largest element using wavelet tree. If not, I would recommend watching this video, in which the concept and applications of wavelet tree are well-explained.

Now you know how to find the $$$k^{th}$$$ largest element, what you have to do is to add another partial sum array on the nodes of the wavelet tree. These partial sum arrays store the sum of $$$a_i$$$ for all indices stored in the node. For convenience, we denote $$$x$$$ as the $$$k^{th}$$$ largest element within the range $$$[l,r]$$$. When you are searching for $$$x$$$ on the wavelet tree, you get to scan through all elements larger than $$$x$$$ in the range $$$[l,r]$$$. You can hence get use of the new partial sum arrays to find the sum of these elements efficiently. Make sure to carefully handle the case where there are multiple copies of $$$x$$$, through. This solution runs in $$$O(n\log (\max (a_i)))$$$, which is quite tight for the given constraints.

Although it is possible for wavelet tree to achieve this, I would recommend using persistent segment tree instead, since persistent segment tree offers a better time complexity ($$$O(n\log n)$$$) in this case. It is also more common for persistent segment trees to appear in other problems or contests, as it can be used to deal with a wider variety of problems. (Fun fact: I have never used wavelet tree in contests since I learned it).

»
18 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

is there a link for the problem?