Queries for elements having values within the range A to B in the given index range using Segment Tree
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: 2
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: 3
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> |
2
Please Login to comment...