Queries for elements greater than K in the given index range using Segment Tree
Last Updated :
29 Oct, 2023
Given an array arr[] of N elements and a number of queries where each query will contain three integers L, R, and K. For each query, the task is to find the number of elements in the subarray arr[L...R] which are greater than K.
Examples:
Input: arr[] = {7, 3, 9, 13, 5, 4}, q[] = {{0, 3, 6}, {1, 5, 8}}
Output:
3
2
Query 1: Only 7, 9 and 13 are greater
than 6 in the subarray {7, 3, 9, 13}.
Query 2: Only 9 and 13 are greater
than 8 in the subarray {3, 9, 13, 5, 4}.
Input: arr[] = {0, 1, 2, 3, 4, 5, 6, 7}, q[] = {{0, 7, 3}, {4, 6, 10}}
Output:
4
0
Prerequisite: Segment tree
Naive approach: Find the answer for each query by simply traversing the array from index l till r and keep adding 1 to the count whenever the array element is greater than k.
Below is the implementation of the above approach:
C++14
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
// Query function to get the answer
// for each query l and r are query range
int query(int arr[], int n, int l, int r, int k)
{
int count = 0;
for (int i = l; i <= r; i++) {
if (arr[i] > k) {
count++;
}
}
return count;
}
// Driver code
int main()
{
int arr[] = { 7, 3, 9, 13, 5, 4 };
int n = sizeof(arr) / sizeof(arr[0]);
// queries
int q[][3] = { { 0, 3, 6 }, { 1, 5, 8 } };
// no. of queries
int num_queries = sizeof(q) / sizeof(q[0]);
for (int i = 0; i < num_queries; i++) {
int l = q[i][0], r = q[i][1], k = q[i][2];
cout << query(arr, n, l, r, k) << endl;
}
return 0;
}
Java
// Added by: Nikunj Sonigara
import java.util.*;
public class Main {
// Query function to get the answer
// for each query l and r are query range
static int query(int[] arr, int n, int l, int r, int k) {
int count = 0;
for (int i = l; i <= r; i++) {
if (arr[i] > k) {
count++;
}
}
return count;
}
public static void main(String[] args) {
int[] arr = { 7, 3, 9, 13, 5, 4 };
int n = arr.length;
// queries
int[][] q = { { 0, 3, 6 }, { 1, 5, 8 } };
// no. of queries
int num_queries = q.length;
for (int i = 0; i < num_queries; i++) {
int l = q[i][0], r = q[i][1], k = q[i][2];
System.out.println(query(arr, n, l, r, k));
}
}
}
Python3
# Added by: Nikunj Sonigara
# Query function to get the answer
# for each query l and r are query range
def query(arr, l, r, k):
count = 0
for i in range(l, r + 1):
if arr[i] > k:
count += 1
return count
# Driver code
if __name__ == "__main__":
arr = [7, 3, 9, 13, 5, 4]
n = len(arr)
# queries
q = [[0, 3, 6], [1, 5, 8]]
# no. of queries
num_queries = len(q)
for i in range(num_queries):
l, r, k = q[i]
print(query(arr, l, r, k))
C#
using System;
class Program
{
// Query function to get the answer
// for each query l and r are query range
static int Query(int[] arr, int l, int r, int k)
{
int count = 0;
for (int i = l; i <= r; i++)
{
if (arr[i] > k)
{
count++;
}
}
return count;
}
// Driver code
static void Main()
{
int[] arr = { 7, 3, 9, 13, 5, 4 };
int n = arr.Length;
// queries
int[,] q = { { 0, 3, 6 }, { 1, 5, 8 } };
// no. of queries
int num_queries = q.GetLength(0);
for (int i = 0; i < num_queries; i++)
{
int l = q[i, 0], r = q[i, 1], k = q[i, 2];
Console.WriteLine(Query(arr, l, r, k));
}
}
}
JavaScript
// Added by: Nikunj Sonigara
// Query function to get the answer
// for each query l and r are query range
function query(arr, l, r, k) {
let count = 0;
for (let i = l; i <= r; i++) {
if (arr[i] > k) {
count++;
}
}
return count;
}
// Driver code
const arr = [7, 3, 9, 13, 5, 4];
const n = arr.length;
// queries
const q = [[0, 3, 6], [1, 5, 8]];
// no. of queries
const numQueries = q.length;
for (let i = 0; i < numQueries; i++) {
const [l, r, k] = q[i];
console.log(query(arr, l, r, k));
}
Output:
3
2
Time Complexity: O(n * q)
Space Complexity: O(1)
Efficient approach: Build a Segment Tree with a vector at each node containing all the elements of the sub-range in sorted order. Answer each query using the segment tree where Binary Search can be used to calculate how many numbers are present in each node whose sub-range lies within the query range which is greater than K. Time complexity of this approach will be O(q * log(n) * log(n))
Below is the implementation of the above approach:
C++
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
// Merge procedure to merge two
// vectors into a single vector
vector<int> merge(vector<int>& v1, vector<int>& v2)
{
int i = 0, j = 0;
// Final vector to return
// after merging
vector<int> v;
// Loop continues until it reaches
// the end of one of the vectors
while (i < v1.size() && j < v2.size()) {
if (v1[i] <= v2[j]) {
v.push_back(v1[i]);
i++;
}
else {
v.push_back(v2[j]);
j++;
}
}
// Here, simply add the remaining
// elements to the vector v
for (int k = i; k < v1.size(); k++)
v.push_back(v1[k]);
for (int k = j; k < v2.size(); k++)
v.push_back(v2[k]);
return v;
}
// Procedure to build the segment tree
void buildTree(vector<int>* tree, int* arr,
int index, int s, int e)
{
// Reached the leaf node
// of the segment tree
if (s == e) {
tree[index].push_back(arr[s]);
return;
}
// Recursively call the buildTree
// on both the nodes of the tree
int mid = (s + e) / 2;
buildTree(tree, arr, 2 * index, s, mid);
buildTree(tree, arr, 2 * index + 1, mid + 1, e);
// Storing the final vector after merging
// the two of its sorted child vector
tree[index] = merge(tree[2 * index], tree[2 * index + 1]);
}
// Query procedure to get the answer
// for each query l and r are query range
int query(vector<int>* tree, int index, int s,
int e, int l, int r, int k)
{
// out of bound or no overlap
if (r < s || l > e)
return 0;
// Complete overlap
// Query range completely lies in
// the segment tree node range
if (s >= l && e <= r) {
// binary search to find index of k
return (tree[index].size()
- (lower_bound(tree[index].begin(),
tree[index].end(), k)
- tree[index].begin()));
}
// Partially overlap
// Query range partially lies in
// the segment tree node range
int mid = (s + e) / 2;
return (query(tree, 2 * index, s,
mid, l, r, k)
+ query(tree, 2 * index + 1, mid + 1,
e, l, r, k));
}
// Function to perform the queries
void performQueries(int L[], int R[], int K[],
int n, int q, vector<int> tree[])
{
for (int i = 0; i < q; i++) {
cout << query(tree, 1, 0, n - 1,
L[i] - 1, R[i] - 1, K[i])
<< endl;
}
}
// Driver code
int main()
{
int arr[] = { 7, 3, 9, 13, 5, 4 };
int n = sizeof(arr) / sizeof(arr[0]);
vector<int> tree[4 * n + 1];
buildTree(tree, arr, 1, 0, n - 1);
// 1-based indexing
int L[] = { 1, 2 };
int R[] = { 4, 6 };
int K[] = { 6, 8 };
// Number of queries
int q = sizeof(L) / sizeof(L[0]);
performQueries(L, R, K, n, q, tree);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG {
// Merge procedure to merge two
// vectors into a single vector
static Vector<Integer> merge(Vector<Integer> v1,
Vector<Integer> v2)
{
int i = 0, j = 0;
// Final vector to return
// after merging
Vector<Integer> v = new Vector<>();
// Loop continues until it reaches
// the end of one of the vectors
while (i < v1.size() && j < v2.size())
{
if (v1.elementAt(i) <= v2.elementAt(j))
{
v.add(v1.elementAt(i));
i++;
}
else
{
v.add(v2.elementAt(j));
j++;
}
}
// Here, simply add the remaining
// elements to the vector v
for (int k = i; k < v1.size(); k++)
v.add(v1.elementAt(k));
for (int k = j; k < v2.size(); k++)
v.add(v2.elementAt(k));
return v;
}
// Procedure to build the segment tree
static void buildTree(Vector<Integer>[] tree, int[] arr,
int index, int s, int e)
{
// Reached the leaf node
// of the segment tree
if (s == e)
{
tree[index].add(arr[s]);
return;
}
// Recursively call the buildTree
// on both the nodes of the tree
int mid = (s + e) / 2;
buildTree(tree, arr, 2 * index, s, mid);
buildTree(tree, arr, 2 * index + 1, mid + 1, e);
// Storing the final vector after merging
// the two of its sorted child vector
tree[index] = merge(tree[2 * index], tree[2 * index + 1]);
}
// Query procedure to get the answer
// for each query l and r are query range
static int query(Vector<Integer>[] tree, int index, int s,
int e, int l, int r, int k)
{
// out of bound or no overlap
if (r < s || l > e)
return 0;
// Complete overlap
// Query range completely lies in
// the segment tree node range
if (s >= l && e <= r)
{
// binary search to find index of k
return (tree[index].size() - lowerBound(tree[index],
tree[index].size(), k));
}
// Partially overlap
// Query range partially lies in
// the segment tree node range
int mid = (s + e) / 2;
return (query(tree, 2 * index, s, mid, l, r, k) +
query(tree, 2 * index + 1, mid + 1, e, l, r, k));
}
// Function to perform the queries
static void performQueries(int L[], int R[], int K[],
int n, int q, Vector<Integer> tree[])
{
for (int i = 0; i < q; i++)
{
System.out.println(query(tree, 1, 0, n - 1,
L[i] - 1, R[i] - 1, K[i]));
}
}
static int lowerBound(Vector<Integer> array,
int length, int value)
{
int low = 0;
int high = length;
while (low < high)
{
final int mid = (low + high) / 2;
if (value <= array.elementAt(mid))
{
high = mid;
}
else
{
low = mid + 1;
}
}
return low;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 7, 3, 9, 13, 5, 4 };
int n = arr.length;
@SuppressWarnings("unchecked")
Vector<Integer>[] tree = new Vector[4 * n + 1];
for (int i = 0; i < (4 * n + 1); i++)
{
tree[i] = new Vector<>();
}
buildTree(tree, arr, 1, 0, n - 1);
// 1-based indexing
int L[] = { 1, 2 };
int R[] = { 4, 6 };
int K[] = { 6, 8 };
// Number of queries
int q = L.length;
performQueries(L, R, K, n, q, tree);
}
}
// This code is contributed by
// sanjeev2552
Python3
# Python3 implementation of the approach
from bisect import bisect_left as lower_bound
# Merge procedure to merge two
# vectors into a single vector
def merge(v1, v2):
i = 0
j = 0
# Final vector to return
# after merging
v = []
# Loop continues until it reaches
# the end of one of the vectors
while (i < len(v1) and j < len(v2)):
if (v1[i] <= v2[j]):
v.append(v1[i])
i += 1
else:
v.append(v2[j])
j += 1
# Here, simply add the remaining
# elements to the vector v
for k in range(i, len(v1)):
v.append(v1[k])
for k in range(j, len(v2)):
v.append(v2[k])
return v
# Procedure to build the segment tree
def buildTree(tree,arr,index, s, e):
# Reached the leaf node
# of the segment tree
if (s == e):
tree[index].append(arr[s])
return
# Recursively call the buildTree
# on both the nodes of the tree
mid = (s + e) // 2
buildTree(tree, arr, 2 * index, s, mid)
buildTree(tree, arr, 2 * index + 1, mid + 1, e)
# Storing the final vector after merging
# the two of its sorted child vector
tree[index] = merge(tree[2 * index], tree[2 * index + 1])
# Query procedure to get the answer
# for each query l and r are query range
def query(tree, index, s, e, l, r, k):
# out of bound or no overlap
if (r < s or l > e):
return 0
# Complete overlap
# Query range completely lies in
# the segment tree node range
if (s >= l and e <= r):
# binary search to find index of k
return len(tree[index]) - (lower_bound(tree[index], k))
# Partially overlap
# Query range partially lies in
# the segment tree node range
mid = (s + e) // 2
return (query(tree, 2 * index, s,mid, l, r, k)
+ query(tree, 2 * index + 1, mid + 1,e, l, r, k))
# Function to perform the queries
def performQueries(L, R, K,n, q,tree):
for i in range(q):
print(query(tree, 1, 0, n - 1,L[i] - 1, R[i] - 1, K[i]))
# Driver code
if __name__ == '__main__':
arr = [7, 3, 9, 13, 5, 4]
n = len(arr)
tree = [[] for i in range(4 * n + 1)]
buildTree(tree, arr, 1, 0, n - 1)
# 1-based indexing
L = [1, 2]
R = [4, 6]
K = [6, 8]
# Number of queries
q = len(L)
performQueries(L, R, K, n, q, tree)
# This code is contributed by mohit kumar 29
C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG {
// Merge procedure to merge two
// vectors into a single vector
static List<int> merge(List<int> v1,
List<int> v2)
{
int i = 0, j = 0;
// Final vector to return
// after merging
List<int> v = new List<int>();
// Loop continues until it reaches
// the end of one of the vectors
while (i < v1.Count && j < v2.Count)
{
if (v1[i] <= v2[j])
{
v.Add(v1[i]);
i++;
}
else
{
v.Add(v2[j]);
j++;
}
}
// Here, simply add the remaining
// elements to the vector v
for (int k = i; k < v1.Count; k++)
v.Add(v1[k]);
for (int k = j; k < v2.Count; k++)
v.Add(v2[k]);
return v;
}
// Procedure to build the segment tree
static void buildTree(List<int>[] tree, int[] arr,
int index, int s, int e)
{
// Reached the leaf node
// of the segment tree
if (s == e)
{
tree[index].Add(arr[s]);
return;
}
// Recursively call the buildTree
// on both the nodes of the tree
int mid = (s + e) / 2;
buildTree(tree, arr, 2 * index, s, mid);
buildTree(tree, arr, 2 * index + 1, mid + 1, e);
// Storing the readonly vector after merging
// the two of its sorted child vector
tree[index] = merge(tree[2 * index], tree[2 * index + 1]);
}
// Query procedure to get the answer
// for each query l and r are query range
static int query(List<int>[] tree, int index, int s,
int e, int l, int r, int k)
{
// out of bound or no overlap
if (r < s || l > e)
return 0;
// Complete overlap
// Query range completely lies in
// the segment tree node range
if (s >= l && e <= r)
{
// binary search to find index of k
return (tree[index].Count - lowerBound(tree[index],
tree[index].Count, k));
}
// Partially overlap
// Query range partially lies in
// the segment tree node range
int mid = (s + e) / 2;
return (query(tree, 2 * index, s, mid, l, r, k) +
query(tree, 2 * index + 1, mid + 1, e, l, r, k));
}
// Function to perform the queries
static void performQueries(int []L, int []R, int []K,
int n, int q, List<int> []tree)
{
for (int i = 0; i < q; i++)
{
Console.WriteLine(query(tree, 1, 0, n - 1,
L[i] - 1, R[i] - 1, K[i]));
}
}
static int lowerBound(List<int> array,
int length, int value)
{
int low = 0;
int high = length;
while (low < high)
{
int mid = (low + high) / 2;
if (value <= array[mid])
{
high = mid;
}
else
{
low = mid + 1;
}
}
return low;
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { 7, 3, 9, 13, 5, 4 };
int n = arr.Length;
List<int>[] tree = new List<int>[4 * n + 1];
for (int i = 0; i < (4 * n + 1); i++)
{
tree[i] = new List<int>();
}
buildTree(tree, arr, 1, 0, n - 1);
// 1-based indexing
int []L = { 1, 2 };
int []R = { 4, 6 };
int []K = { 6, 8 };
// Number of queries
int q = L.Length;
performQueries(L, R, K, n, q, tree);
}
}
// This code is contributed by PrinciRaj1992
JavaScript
<script>
// JavaScript implementation of the approach
// Merge procedure to merge two
// vectors into a single vector
function merge(v1, v2) {
let i = 0, j = 0;
// Final vector to return
// after merging
let v = new Array();
// Loop continues until it reaches
// the end of one of the vectors
while (i < v1.length && j < v2.length) {
if (v1[i] <= v2[j]) {
v.push(v1[i]);
i++;
}
else {
v.push(v2[j]);
j++;
}
}
// Here, simply add the remaining
// elements to the vector v
for (let k = i; k < v1.length; k++)
v.push(v1[k]);
for (let k = j; k < v2.length; k++)
v.push(v2[k]);
return v;
}
// Procedure to build the segment tree
function buildTree(tree, arr, index, s, e) {
// Reached the leaf node
// of the segment tree
if (s == e) {
tree[index].push(arr[s]);
return;
}
// Recursively call the buildTree
// on both the nodes of the tree
let mid = Math.floor((s + e) / 2);
buildTree(tree, arr, 2 * index, s, mid);
buildTree(tree, arr, 2 * index + 1, mid + 1, e);
// Storing the final vector after merging
// the two of its sorted child vector
tree[index] = merge(tree[2 * index], tree[2 * index + 1]);
}
// Query procedure to get the answer
// for each query l and r are query range
function query(tree, index, s, e, l, r, k) {
// out of bound or no overlap
if (r < s || l > e)
return 0;
// Complete overlap
// Query range completely lies in
// the segment tree node range
if (s >= l && e <= r) {
// binary search to find index of k
return (tree[index].length
- (lowerBound(tree[index], tree[index].length, k)));
}
// Partially overlap
// Query range partially lies in
// the segment tree node range
let mid = Math.floor((s + e) / 2);
return (query(tree, 2 * index, s,
mid, l, r, k)
+ query(tree, 2 * index + 1, mid + 1,
e, l, r, k));
}
function lowerBound(array, length, value) {
let low = 0;
let high = length;
while (low < high) {
let mid = Math.floor((low + high) / 2);
if (value <= array[mid]) {
high = mid;
}
else {
low = mid + 1;
}
}
return low;
}
// Function to perform the queries
function performQueries(L, R, K, n, q, tree) {
for (let i = 0; i < q; i++) {
document.write(
query(tree, 1, 0, n - 1, L[i] - 1, R[i] - 1, K[i]) +
"<br>"
);
}
}
// Driver code
let arr = [7, 3, 9, 13, 5, 4];
let n = arr.length;
let tree = new Array();
for (let i = 0; i < 4 * n + 1; i++) {
tree.push([])
}
buildTree(tree, arr, 1, 0, n - 1);
// 1-based indexing
let L = [1, 2];
let R = [4, 6];
let K = [6, 8];
// Number of queries
let q = L.length;
performQueries(L, R, K, n, q, tree);
</script>
The space complexity of the segment tree is O(n log n). The tree has at most 4n nodes, and each node stores a vector of size at most n, which leads to the space complexity of O(n log n).
Another Approach:
Another way of doing it using segment trees is by storing the first element greater than K in each node (if present) in that range, otherwise storing 0.
Here, we need to consider 3 cases for building the tree.
- If both left and right children contain a number other than 0, the answer is always the left child. (we need to consider the very first occurrence of the number greater than K.)
- If any one of the left or right child contains 0, the answer is always a number other than 0.
- If both left and right children contain 0, the answer is always 0 (indicating that no number greater than K is present in that range).
The query function remains the same as always.
Consider the following example: arr[] = {7, 3, 9, 13, 5, 4} , K = 6
The tree in this case will look like this:

Below is the implementation of the above approach:
C++
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
vector<int> arr(1000000), tree(4 * arr.size());
// combine function to make parent node
int combine(int a, int b)
{
if (a != 0 && b != 0) {
return a;
}
if (a >= b) {
return a;
}
return b;
}
// building the tree
void buildTree(int ind, int low, int high, int x)
{
// leaf node
if (low == high) {
if (arr[low] > x) {
tree[ind] = arr[low];
}
else {
tree[ind] = 0;
}
return;
}
int mid = (low + high) / 2;
buildTree(2 * ind + 1, low, mid, x);
buildTree(2 * ind + 2, mid + 1, high, x);
// merging the nodes while backtracking.
tree[ind]
= combine(tree[2 * ind + 1], tree[2 * ind + 2]);
}
// performing query
int query(int ind, int low, int high, int l, int r)
{
int mid = (low + high) / 2;
// Out of Bounds
if (low > r || high < l) {
return 0;
}
// completely overlaps
if (l <= low && r >= high) {
return tree[ind];
}
// partially overlaps
return combine(query(2 * ind + 1, low, mid, l, r),
query(2 * ind + 2, mid + 1, high, l, r));
}
// Driver Code
int main()
{
arr = { 7, 3, 9, 13, 5, 4 };
int n = 6;
int k = 6;
// 1-based indexing
int l = 1, r = 4;
buildTree(0, 0, n - 1, k);
cout << query(0, 0, n - 1, l - 1, r - 1);
return 0;
}
// This code is contributed by yashbeersingh42
Java
// Java implementation of the approach
public class GFG {
int[] arr, tree;
// combine function to make parent node
int combine(int a, int b)
{
if (a != 0 && b != 0) {
return a;
}
if (a >= b) {
return a;
}
return b;
}
// building the tree
void buildTree(int ind, int low, int high, int x)
{
// leaf node
if (low == high) {
if (arr[low] > x) {
tree[ind] = arr[low];
}
else {
tree[ind] = 0;
}
return;
}
int mid = (high - low) / 2 + low;
buildTree(2 * ind + 1, low, mid, x);
buildTree(2 * ind + 2, mid + 1, high, x);
// merging the nodes while backtracking
tree[ind]
= combine(tree[2 * ind + 1], tree[2 * ind + 2]);
}
// performing query
int query(int ind, int low, int high, int l, int r)
{
int mid = (high - low) / 2 + low;
// Out of Bounds
if (low > r || high < l) {
return 0;
}
// completely overlaps
if (l <= low && r >= high) {
return tree[ind];
}
// partially overlaps
return combine(
query(2 * ind + 1, low, mid, l, r),
query(2 * ind + 2, mid + 1, high, l, r));
}
// Driver Code
public static void main(String args[])
{
GFG ob = new GFG();
ob.arr = new int[] { 7, 3, 9, 13, 5, 4 };
int n = ob.arr.length;
int k = 6;
ob.tree = new int[4 * n];
// 1-based indexing
int l = 1, r = 4;
ob.buildTree(0, 0, n - 1, k);
System.out.println(
ob.query(0, 0, n - 1, l - 1, r - 1));
}
}
// This code is contributed by sarvjot.
Python3
# Python implementation of the approach
import math
# combine function to make parent node
def combine(a, b):
if a != 0 and b != 0:
return a
if a >= b:
return a
return b
# building the tree
def build_tree(arr, tree, ind, low, high, x):
# leaf node
if low == high:
if arr[low] > x:
tree[ind] = arr[low]
else:
tree[ind] = 0
return
mid = (high - low) / 2 + low
mid = math.floor(mid)
mid = int(mid)
build_tree(arr, tree, 2 * ind + 1, low, mid, x)
build_tree(arr, tree, 2 * ind + 2, mid + 1, high, x)
# merging the nodes while backtracking
tree[ind] = combine(tree[2 * ind + 1], tree[2 * ind + 2])
# performing query
def query(tree, ind, low, high, l, r):
mid = (high - low) / 2 + low
mid = math.floor(mid)
mid = int(mid)
# out of bounds
if low > r or high < l:
return 0
# complete overlaps
if l <= low and r >= high:
return tree[ind]
# partial overlaps
q1 = query(tree, 2 * ind + 1, low, mid, l, r)
q2 = query(tree, 2 * ind + 2, mid + 1, high, l, r)
return combine(q1, q2)
# Driver Code
if __name__ == '__main__':
arr = [7, 3, 9, 13, 5, 4]
n = len(arr)
k = 6
tree = [[] for i in range(4 * n)]
# 1-based indexing
l = 1
r = 4
build_tree(arr, tree, 0, 0, n - 1, k)
print(query(tree, 0, 0, n - 1, l - 1, r - 1))
# This code is contributed by sarvjot.
C#
// C# implementation of the approach
using System;
class GFG {
static int[] arr, tree;
// combine function to make parent node
static int combine(int a, int b)
{
if (a != 0 && b != 0) {
return a;
}
if (a >= b) {
return a;
}
return b;
}
// building the tree
static void buildTree(int ind, int low, int high, int x)
{
// leaf node
if (low == high) {
if (arr[low] > x) {
tree[ind] = arr[low];
}
else {
tree[ind] = 0;
}
return;
}
int mid = (high - low) / 2 + low;
buildTree(2 * ind + 1, low, mid, x);
buildTree(2 * ind + 2, mid + 1, high, x);
// merging the nodes while backtracking
tree[ind]
= combine(tree[2 * ind + 1], tree[2 * ind + 2]);
}
// performing query
static int query(int ind, int low, int high, int l, int r)
{
int mid = (high - low) / 2 + low;
// Out of Bounds
if (low > r || high < l) {
return 0;
}
// completely overlaps
if (l <= low && r >= high) {
return tree[ind];
}
// partially overlaps
return combine(
query(2 * ind + 1, low, mid, l, r),
query(2 * ind + 2, mid + 1, high, l, r));
}
static void Main() {
arr = new int[] { 7, 3, 9, 13, 5, 4 };
int n = arr.Length;
int k = 6;
tree = new int[4 * n];
// 1-based indexing
int l = 1, r = 4;
buildTree(0, 0, n - 1, k);
Console.Write(query(0, 0, n - 1, l - 1, r - 1));
}
}
// This code is contributed by suresh07.
JavaScript
<script>
// Javascript implementation of the approach
let arr, tree;
// combine function to make parent node
function combine(a, b)
{
if (a != 0 && b != 0) {
return a;
}
if (a >= b) {
return a;
}
return b;
}
// building the tree
function buildTree(ind, low, high, x)
{
// leaf node
if (low == high) {
if (arr[low] > x) {
tree[ind] = arr[low];
}
else {
tree[ind] = 0;
}
return;
}
let mid = parseInt((high - low) / 2, 10) + low;
buildTree(2 * ind + 1, low, mid, x);
buildTree(2 * ind + 2, mid + 1, high, x);
// merging the nodes while backtracking
tree[ind]
= combine(tree[2 * ind + 1], tree[2 * ind + 2]);
}
// performing query
function query(ind, low, high, l, r)
{
let mid = parseInt((high - low) / 2, 10) + low;
// Out of Bounds
if (low > r || high < l) {
return 0;
}
// completely overlaps
if (l <= low && r >= high) {
return tree[ind];
}
// partially overlaps
return combine(
query(2 * ind + 1, low, mid, l, r),
query(2 * ind + 2, mid + 1, high, l, r));
}
arr = [ 7, 3, 9, 13, 5, 4 ];
let n = arr.length;
let k = 6;
tree = new Array(4 * n);
tree.fill(0);
// 1-based indexing
let l = 1, r = 4;
buildTree(0, 0, n - 1, k);
document.write(query(0, 0, n - 1, l - 1, r - 1));
// This code is contributed by divyesh072019.
</script>
Output:
7
Time Complexity: O(N * log N) to build the tree and O(log N) for each query.
Space Complexity: O(N)
Similar Reads
Queries for the count of even digit sum elements in the given range using Segment Tree.
Given an array arr[] of N elements, the task is to answer Q queries each having two integers L and R. For each query, the task is to find the number of elements in the subarray arr[L...R] whose digit sum is even.Examples: Input: arr[] = {7, 3, 19, 13, 5, 4} query = { 1, 5 } Output: 3 Explanation: El
15+ min read
Number of elements greater than K in the range L to R using Fenwick Tree (Offline queries)
Prerequisites: Fenwick Tree (Binary Indexed Tree)Given an array of N numbers, and a number of queries where each query will contain three numbers(l, r and k). The task is to calculate the number of array elements that are greater than K in the subarray[L, R]. Examples: Input: n=6 q=2 arr[ ] = { 7, 3
15+ min read
Find the element having maximum set bits in the given range for Q queries
Given an array arr[] of N integers and Q queries, each query having two integers L and R, the task is to find the element having maximum set bits in the range L to R. Note: If there are multiple elements having maximum set bits, then print the maximum of those. Examples: Input: arr[] = {18, 9, 8, 15
15+ min read
Find the kth element in the series generated by the given N ranges
Given N non-overlapping ranges L[] and R[] where the every range starts after the previous range ends i.e. L[i] > R[i - 1] for all valid i. The task is to find the Kth element in the series which is formed after sorting all the elements in all the given ranges in ascending order.Examples: Input:
10 min read
Queries for the minimum element in an array excluding the given index range
Given an array arr[] of N integers and Q queries where each query consists of an index range [L, R]. For each query, the task is to find the minimum element in the array excluding the elements from the given index range. Examples: Input: arr[] = {3, 2, 1, 4, 5}, Q[][] = {{1, 2}, {2, 3}} Output: 3 2
15+ min read
Find element with maximum weight in given price range for Q queries
Given an array arr[] of size N where each element denotes a pair in the form (price, weight) denoting the price and weight of each item. Given Q queries of the form [X, Y] denoting the price range. The task is to find the element with the highest weight within a given price range for each query. Exa
11 min read
Number of segments where all elements are greater than X
Given an array of N integers and a number X, the task is to find the number of segments such that all elements in the segment are greater than X. The count should not include overlapping segments and two or more contiguous segments should be considered as one. Examples: Input: a[] = {3, 4, 5, 6, 7,
11 min read
Find the number of elements greater than k in a sorted array
Given a sorted array arr[] of integers and an integer k, the task is to find the count of elements in the array which are greater than k. Note that k may or may not be present in the array.Examples: Input: arr[] = {2, 3, 5, 6, 6, 9}, k = 6 Output: 1Input: arr[] = {1, 1, 2, 5, 5, 7}, k = 8 Output: 0
7 min read
Queries for k-th smallest in given ranges
Given n ranges of the form [l, r] and an integer q denoting the number of queries. The task is to return the kth smallest element for each query (assume k>1) after combining all the ranges. In case the kth smallest element doesn't exist, return -1. Examples : Input: n = 2, q = 3, range[] = {{1, 4
15+ min read
Number of nodes greater than a given value in n-ary tree
Given a n-ary tree and a number x, find and return the number of nodes which are greater than x. Example: In the given tree, x = 7 Number of nodes greater than x are 4. Approach: The idea is maintain a count variable initialize to 0. Traverse the tree and compare root data with x. If root data is gr
6 min read