i_love_turtles's blog

By i_love_turtles, 16 months ago, In English

Hi guys. Recently, i have been thinking about a new problem but I can't even come up the solution myself LOL. Any ideas to solve this? (Sorry for my poor English btw)

Statement:

Given an array a consists of N integers (-1e6 <= a[i] <= 1e6). You have to answer Q queries, each of them you are given:

t L R k

  • If t = 1, return to sum of k largest numbers in range [L, R]
  • If t = 2, return to sum of k smallest numbers in range [L, R]

Given that both N and Q are smaller than $$$10 ^ {5}$$$. How do we suppose to solve this problem? Is it solvable if the constraints of N, Q up to 2.$$$10 ^ {5}$$$?

  • Vote: I like it
  • +18
  • Vote: I do not like it

»
16 months ago, # |
  Vote: I like it +9 Vote: I do not like it

square root?

»
16 months ago, # |
Rev. 3   Vote: I like it +19 Vote: I do not like it

I'll show how to handle queries of type 2 in $$$\mathcal{O}\left(n \log n + q \log^2 n\right)$$$ time and $$$\mathcal{O}\left(n \log n\right)$$$ auxiliary memory. Queries of type 1 can be handled almost identically.

The main idea is to start with all elements of the array "deactivated" and "activate" each element in increasing order, breaking ties arbitrarily. We'll maintain a persistent segment tree where each node stores the number of activated elements in its segment and the sum of those elements.

Example

So far, our time complexity is $$$\mathcal{O}\left(n \log n\right)$$$ for sorting the array's indices and $$$\mathcal{O}\left(\log n\right)$$$ for each of the $$$n$$$ activated elements, for a total of $$$\mathcal{O}\left(n \log n\right)$$$ time. Also, since the segment tree is persistent, each activation copies all of the $$$\mathcal{O}\left(\log n\right)$$$ nodes on the path to some leaf, for a total of $$$\mathcal{O}\left(n \log n\right)$$$ auxiliary space.

For a query of the form 2 L R k, we need to find the sum of the k smallest elements in [L, R]. Note that as elements were activated, the number of activated elements in each subarray was non-decreasing. Therefore, we can binary search for the time t at which the subarray [L, R] has k activated elements. This takes $$$\mathcal{O}\left(\log n\right)$$$ queries, each of which takes $$$\mathcal{O}\left(\log n\right)$$$ time. We know that at time t, the activated elements in [L, R] are exactly the k smallest elements in that interval: by the definition of t, exactly k elements are activated, and they were activated in increasing order. Finally, query the sum of those elements in [L, R] at that time t in $$$\mathcal{O}\left(\log n\right)$$$ time. This answers each query in $$$\mathcal{O}\left(\log^2 n\right)$$$ time.

To handle queries of type 1, do the same precomputation, but activate the elements in decreasing order instead.

  • »
    »
    16 months ago, # ^ |
      Vote: I like it +11 Vote: I do not like it

    I got it!! Thank you for your dedication and that's detailed explanation :)