Below assumes the elements in your array are all positive
how about not maintaining segment tree for specific k
but resolving the query instead
Just consider your segment tree.
At each node Node_i
, you know:
- its covering sum:
s_i
- the number of elements it covers:
n_i
So two steps:
- For a given range query, get down to the corresponding node
Node_i
.
- For that
Node_i
, s_i
is the sum of its two children's sum. For each of those given child Node_j
with its n_j
elements covered: two possibilities
n_j*k < s_j
:all elements are less than k
n_j*k >= s_j
:at least one element is greater or equal than k
So first case, the child's sum is already valid, nothing more to do.
Second case, you have to explore the child and so forth until nothing more to do
At some point, (if you have an invalid element) you will reach a bottom of the tree: that very node (also an elem) is bad, and you backtrack that fact.
When you get back to your node Node_i
, you substract from s_i
all those bad leaf node's value you found.
pseudo code is:
#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