Ниже предполагается, что все элементы в вашем массиве положительные
как насчет того, чтобы не поддерживать дерево сегментов для конкретного k
, а вместо этого разрешать запрос
Просто рассмотрите вашисегментное дерево.
В каждом узле Node_i
вы знаете:
- его покрывающая сумма:
s_i
- количество охватываемых элементов:
n_i
Итак, два шага:
- Для данного запроса диапазона перейдите к соответствующему узлу
Node_i
. - Для этого
Node_i
, s_i
сумма двух детей. Для каждого из данных дочерних элементов Node_j
с охватываемыми элементами n_j
: две возможности n_j*k < s_j
: все элементы меньше k n_j*k >= s_j
: хотя бы один элемент равенбольше или равно k
Итак, в первом случае сумма ребенка уже действительна, делать больше нечего.
Во втором случае вы должныисследовать ребенка и так далее до тех пор, пока ничего больше не нужно делать
В какой-то момент (если у вас есть недопустимый элемент) вы достигнете низа дерева: этот самый узел (также элемент) плохой, ивы вернетесь к этому факту. Когда вы вернетесь к своему узлу Node_i
, вы вычтете из s_i
все найденные вами значения этих плохих конечных узлов.
псевдокод:
#node is like:
#children:[c1, c2]
#n:number of elem covered
#sum: sum of all elemens it covers
#returns the sum of the covered elements whose value is __greater__ or equal than k
def explore(node, k):
#terminal case
if node.n == 1:
if node.sum >= k:
return node.sum
# when the range query is of size 1...,
# you may want to handle that elsewhere (e.g before calling explore)
return 0
end
#standard case
[c1,c2] = node.children
totalsum = 0
if c1.n * k < c1.sum
#all your elems are less than k, substract nothing
totalsum += 0
else
totalsum += explore(c1, k)
#same for c2...
return totalsum