Skip to content
Related Articles

Related Articles

Improve Article
Queries for elements having values within the range A to B in the given index range using Segment Tree
  • Difficulty Level : Hard
  • Last Updated : 03 Jun, 2021

Given an array arr[] of N elements and two integers A to B, 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] which lies within the range A to B (both included).

Examples: 

Input: arr[] = {7, 3, 9, 13, 5, 4}, A=4, B=7 
query = { 1, 5 } 
Output:
Explanation : 
Only 5 and 4 lies within 4 to 7 
in the subarray {3, 9, 13, 5, 4}.

Input: arr[] = {0, 1, 2, 3, 4, 5, 6, 7}, A=1, B=5 
query = { 3, 5 } 
Output:
Explanation : 
All the elements 3, 4 and 5 lies within 1 to 5 
in the subarray {3, 4, 5}.

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 lies within the range A to B. Time Complexity of this approach will be O(n * q).



Efficient approach: 
Build a Segment Tree.
Representation of Segment trees 
1. Leaf Nodes are the elements of the input array. 
2. Each internal node contains the number of leaves which lies within the range A to B of all leaves under it.

Construction of Segment Tree from given array 
We start with a segment arr[0 . . . n-1]. and every time we divide the current segment into two halves(if it has not yet become a segment of length 1), and then call the same procedure on both halves, and for each such segment, we store the number of elements which lies within the range A to B of all nodes under it.
Time complexity of this approach will be O(q * log(n))

Below is the implementation of the above approach:  

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Procedure to build the segment tree
void buildTree(vector<int>& tree, int* arr,
               int index, int s, int e, int A, int B)
{
 
    // Reached the leaf node
    // of the segment tree
    if (s == e) {
        if (arr[s] >= A && arr[s] <= B)
            tree[index] = 1;
        else
            tree[index] = 0;
        return;
    }
 
    // Recursively call the buildTree
    // on both the nodes of the tree
    int mid = (s + e) / 2;
    buildTree(tree, arr, 2 * index, s, mid, A, B);
    buildTree(tree, arr, 2 * index + 1, mid + 1, e, A, B);
 
    tree[index] = 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)
{
 
    // 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) {
        return tree[index];
    }
 
    // 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)
            + query(tree, 2 * index + 1, mid + 1, e, l, r));
}
 
// 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);
 
    int L = 1, R = 5, A = 4, B = 7;
 
    buildTree(tree, arr, 1, 0, n - 1, A, B);
 
    cout << query(tree, 1, 0, n - 1, L, R)
         << endl;
    return 0;
}

Java




// Java implementation of the approach
class GFG{
     
// Procedure to build the segment tree
static void buildTree(int tree[] , int arr[] ,
                      int index, int s, int e,
                      int A, int B)
{
     
    // Reached the leaf node
    // of the segment tree
    if (s == e)
    {
        if (arr[s] >= A && arr[s] <= B)
            tree[index] = 1;
        else
            tree[index] = 0;
             
        return;
    }
 
    // Recursively call the buildTree
    // on both the nodes of the tree
    int mid = (s + e) / 2;
    buildTree(tree, arr, 2 * index,
              s, mid, A, B);
    buildTree(tree, arr, 2 * index + 1,
              mid + 1, e, A, B);
 
    tree[index] = 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(int tree[], int index, int s,
                 int e, int l, int r)
{
     
    // 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)
    {
        return tree[index];
    }
 
    // 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) +
            query(tree, 2 * index + 1,
                  mid + 1, e, l, r));
}
 
// Driver code
public static void main (String []args)
{
    int arr[] = { 7, 3, 9, 13, 5, 4 };
    int n = arr.length;
    int tree[] = new int [(4 * n + 1)];
 
    int L = 1, R = 5, A = 4, B = 7;
 
    buildTree(tree, arr, 1, 0, n - 1, A, B);
 
    System.out.print(query(tree, 1, 0, n - 1, L, R));
}
}
 
// This code is contributed by chitranayal

Python3




# Python3 implementation of the approach
 
# Procedure to build the segment tree
def buildTree(tree,arr,index, s, e, A, B):
 
    # Reached the leaf node
    # of the segment tree
    if (s == e):
        if (arr[s] >= A and arr[s] <= B):
            tree[index] = 1
        else:
            tree[index] = 0
        return
 
    # Recursively call the buildTree
    # on both the nodes of the tree
    mid = (s + e) // 2
    buildTree(tree, arr, 2 * index, s, mid, A, B)
    buildTree(tree, arr, 2 * index + 1, mid + 1, e, A, B)
 
    tree[index] = 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):
 
    # 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):
        return tree[index]
 
    # 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)
            + query(tree, 2 * index + 1, mid + 1, e, l, r))
 
# Driver code
if __name__ == '__main__':
    arr=[7, 3, 9, 13, 5, 4]
    n = len(arr)
    tree=[0]*(4 * n + 1)
 
    L = 1
    R = 5
    A = 4
    B = 7
 
    buildTree(tree, arr, 1, 0, n - 1, A, B)
 
    print(query(tree, 1, 0, n - 1, L, R))
 
# This code is contributed by mohit kumar 29

C#




// C# implementation of the approach
using System;
 
class GFG{
     
// Procedure to build the segment tree
static void buildTree(int[] tree, int[] arr,
                      int index, int s, int e,
                      int A, int B)
{
     
    // Reached the leaf node
    // of the segment tree
    if (s == e)
    {
        if (arr[s] >= A && arr[s] <= B)
            tree[index] = 1;
        else
            tree[index] = 0;
             
        return;
    }
 
    // Recursively call the buildTree
    // on both the nodes of the tree
    int mid = (s + e) / 2;
    buildTree(tree, arr, 2 * index,
              s, mid, A, B);
    buildTree(tree, arr, 2 * index + 1,
              mid + 1, e, A, B);
 
    tree[index] = 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(int[] tree, int index, int s,
                 int e, int l, int r)
{
     
    // 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)
    {
        return tree[index];
    }
 
    // 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) +
            query(tree, 2 * index + 1,
                  mid + 1, e, l, r));
}
 
// Driver code
public static void Main ()
{
    int[] arr = new int[] { 7, 3, 9, 13, 5, 4 };
    int n = arr.Length;
    int[] tree = new int [(4 * n + 1)];
 
    int L = 1, R = 5, A = 4, B = 7;
 
    buildTree(tree, arr, 1, 0, n - 1, A, B);
 
    Console.Write(query(tree, 1, 0, n - 1, L, R));
}
}
 
// This code is contributed by sanjoy_62

Javascript




<script>
 
// Javascript implementation of the approach
 
// Procedure to build the segment tree
function buildTree(tree, arr, index, s, e, A, B)
{
     
    // Reached the leaf node
    // of the segment tree
    if (s == e)
    {
        if (arr[s] >= A && arr[s] <= B)
            tree[index] = 1;
        else
            tree[index] = 0;
               
        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, A, B);
    buildTree(tree, arr, 2 * index + 1,
              mid + 1, e, A, B);
   
    tree[index] = 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)
{
     
    // 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)
    {
        return tree[index];
    }
   
    // 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) +
            query(tree, 2 * index + 1,
                  mid + 1, e, l, r));
}
 
// Driver code
let arr = [ 7, 3, 9, 13, 5, 4 ];
let n = arr.length;
let tree = new Array(4 * n + 1);
let L = 1, R = 5, A = 4, B = 7;
buildTree(tree, arr, 1, 0, n - 1, A, B);
 
document.write(query(tree, 1, 0, n - 1, L, R));
 
// This code is contributed by avanitrachhadiya2155
 
</script>
Output: 
2

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer DSA Live Classes




My Personal Notes arrow_drop_up
Recommended Articles
Page :