简体   繁体   中英

kth order statistic in range [i, j]

There is a problem but I can't find a efficient algorithm for it.

Problem

Given an array of numbers a[1], ..., a[n] , we get queries of the kind:

  • SELECT(i, j, k) : find k-th smallest number in range [i, j] after sorting a[i], a[i+1], ..., a[j]
  • SET(i, value) : perform a[i] = value

Example

Input:

5 5 // n = 5 (size of array), m = 5 (number of query)
5 10 9 6 7
select 2 4 1
select 2 4 2
set 3 12
set 4 15
select 2 4 1

Output:

6
9
10

I think that we can implement this with Merge Sort Tree ( Special segment tree ). I found this in internet: merge sort tree for range order statistics

but because we can change array value, this algorithm in not efficient.
Is it possible to help me, How can I implement it efficiently?
Thanks.

I don't know about the merge-sort-tree but I can think of different data-structure / algorithm that gives you the desire output in O(n) per query.

Notice solution for this problem depends on the distribution between SET and SELECT queries -> I assume there are more SELECT 's so I tried to lower that complexity. If you have more SET 's then I would use @miradham answer:

        david    miradham 
SET      O(n)      O(1)
SELECT   O(n)      O(nlogn)
Space    O(n)      O(n)

Both solution are space complexity of O(n) .

In your question you used indexes that start from 1 -> I will modify it to start from 0.

Let look at your example: a = array (5, 10, 9, 6, 7) . As pre-processing we will create sorted array that contains also the original index of the elements -> b = array(5(0), 6(3), 7(4), 9(2), 10(1)) when the number in bracket is the index in the original array a . This can be done in O(nlogn) .

How do we deals with the queries?

SELECT(i, j, k) :

let cnt = 1;
for m in b (sorted array)
    if m(index) <= i && m(index) <= j // the index is in given range
        if (cnt == k)
            return k // found the k lowest
        else cnt++

This is O(n) as you loop over b

SET(i, value) :

Changing a is easy and can be done in O(1) . Changing b :

originalValue = a[i] // old value
Add [value(i)] to b as new element // O(logn) as b sorted
Remove [originalValue(i)] from b // b sorted but array implementation may cause O(n)

Total of O(n)

If further explanation is needed feel free to ask. Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM