# Segment Tree Node
class Node:
# minimum value in the range
def __init__(self):
self.min = None
# count of the minimum value in the range
self.cnt = None
# function to construct the tree
def buildtree(low, high, pos, arr, tree):
# base condition
if low == high:
# leaf Node has arr single element
tree[pos].min = arr[low]
tree[pos].cnt = 1
return
mid = (low + high) >> 1
# left-subtree
buildtree(low, mid, 2 * pos + 1, arr, tree)
# right-subtree
buildtree(mid + 1, high, 2 * pos + 2, arr, tree)
# left subtree has the minimum element
if tree[2 * pos + 1].min < tree[2 * pos + 2].min:
tree[pos].min = tree[2 * pos + 1].min
tree[pos].cnt = tree[2 * pos + 1].cnt
# right subtree has the minimum element
elif tree[2 * pos + 1].min > tree[2 * pos + 2].min:
tree[pos].min = tree[2 * pos + 2].min
tree[pos].cnt = tree[2 * pos + 2].cnt
# both subtree has the same minimum element
else:
tree[pos].min = tree[2 * pos + 1].min
tree[pos].cnt = tree[2 * pos + 1].cnt + tree[2 * pos + 2].cnt
# function that answers every query
def query(s, e, low, high, pos, tree):
h = Node()
# out of range
if e < low or s > high:
h.min = h.cnt = float('inf')
return h
# in range
if s >= low and e <= high:
return tree[pos]
mid = (s + e) >> 1
# left-subtree
ans1 = query(s, mid, low, high, 2 * pos + 1, tree)
# right-subtree
ans2 = query(mid + 1, e, low, high, 2 * pos + 2, tree)
ans = Node()
ans.min = min(ans1.min, ans2.min)
# add count when min is same of both subtree
if ans1.min == ans2.min:
ans.cnt = ans2.cnt + ans1.cnt
# store the minimal's count
elif ans1.min < ans2.min:
ans.cnt = ans1.cnt
else:
ans.cnt = ans2.cnt
return ans
def solveQueries(arr, queries):
n = len(arr)
# create a segment tree
tree = [Node() for _ in range(4 * n)]
buildtree(0, n - 1, 0, arr, tree)
# to store the results
res = []
for q in queries:
l, r = q[0], q[1]
ans = query(0, n - 1, l, r, 0, tree).cnt
res.append(ans)
return res
if __name__ == "__main__":
arr = [1, 1, 2, 4, 3, 3]
queries = [[0, 2], [2, 5]]
res = solveQueries(arr, queries)
for i in res:
print(i, end=" ")