Skip to content
Related Articles
Open in App
Not now

Related Articles

Queries for elements having values within the range A to B in the given index range using Segment Tree

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 03 Jun, 2021
Improve Article
Save Article

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

 


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!