Skip to content
Related Articles

Related Articles

Save Article
Improve Article
Save Article
Like Article

Queries for count of array elements with values in given range with updates

  • Last Updated : 11 Jun, 2021

Given an array arr[] of size N and a matrix Q consisting of queries of the following two types: 

  • 1 L R : Print the number of elements lying in the range [L, R].
  • 2 i x : Set arr[i] = x

Examples: 

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 experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: arr[] = {1, 2, 2, 3, 4, 4, 5, 6}, Q = {{1, {3, 5}}, {1, {2, 4}}, {1, {1, 2}}, {2, {1, 7}}, {1, {1, 2}}} 
Output: 4 5 3 2 
Explanation: 
Array elements from the range [3, 5] are {3, 4, 4, 5} 
Array elements from the range [2, 4] are {2, 2, 3, 4, 4} 
Array elements from the range [1, 2] are {1, 2, 2} 
Replacing arr[1] by 7 modifies the array to {1, 7, 2, 3, 4, 4, 5, 6} 
Elements that lie in range [1, 2] are {1, 2}



Input: arr = {5, 5, 1, 3, 4, 4, 2, 3}, Q = {{1, {3, 6}}, {1, {2, 4}}, {1, {10, 20}}} 
Output: 6 5 0 
Explanation: 
Array elements from the range [3, 6] are {3, 3, 4, 4, 5, 5} 
Array elements from the range [2, 4] are {2, 3, 3, 4, 4} 
No element from the range [10, 20] exists in the array. 

Naive Approach: 
The simplest approach to solve this problem is as follows: 

  • For the query of type (1 L R), iterate over the entire array and count the number of elements in the array such that L ≤ arr[i] ≤ R. Finally, print the count.
  • For the query of type (2 i x), replace arr[i] by x.

Below is the implementation of the above approach:

C++




// C++ code for queries for number
// of elements that lie in range
// [l, r] (with updates)
#include <bits/stdc++.h>
using namespace std;
 
// Function to set arr[index] = x
void setElement(int* arr, int n,
                int index, int x)
{
    arr[index] = x;
}
 
// Function to get count of elements
// that lie in range [l, r]
int getCount(int* arr, int n,
            int l, int r)
{
    int count = 0;
 
    // Traverse array
    for (int i = 0; i < n; i++) {
 
        // If element lies in the
        // range [L, R]
        if (arr[i] >= l
            && arr[i] <= r) {
 
            // Increase count
            count++;
        }
    }
    return count;
}
 
// Function to solve each query
void SolveQuery(int arr[], int n,
                vector<pair<int,
                            pair<int, int> > >
                    Q)
{
    int x;
 
    for (int i = 0; i < Q.size(); i++) {
        if (Q[i].first == 1) {
            x = getCount(arr, n,
                        Q[i].second.first,
                        Q[i].second.second);
 
            cout << x << " ";
        }
        else {
            setElement(arr, n,
                    Q[i].second.first,
                    Q[i].second.second);
        }
    }
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 2, 2, 3, 4, 4, 5, 6 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    vector<pair<int, pair<int, int> > > Q
        = { { 1, { 3, 5 } },
            { 1, { 2, 4 } },
            { 1, { 1, 2 } },
            { 2, { 1, 7 } },
            { 1, { 1, 2 } } };
    SolveQuery(arr, n, Q);
 
    return 0;
}

Java




// Java code for queries for number
// of elements that lie in range
// [l, r] (with updates)
import java.util.*;
import java.lang.*;
 
class GFG{
     
// Function to set arr[index] = x
static void setElement(int[] arr, int n,
                       int index, int x)
{
    arr[index] = x;
}
 
// Function to get count of elements
// that lie in range [l, r]
static int getCount(int[] arr, int n,
                    int l, int r)
{
    int count = 0;
     
    // Traverse array
    for(int i = 0; i < n; i++)
    {
         
        // If element lies in the
        // range [L, R]
        if (arr[i] >= l && arr[i] <= r)
        {
            // Increase count
            count++;
        }
    }
    return count;
}
 
// Function to solve each query
static void SolveQuery(int arr[], int n,
                       ArrayList<List<Integer>> Q)
{
    int x;
  
    for(int i = 0; i < Q.size(); i++)
    {
        if (Q.get(i).get(0) == 1)
        {
            x = getCount(arr, n,
                         Q.get(i).get(1),
                         Q.get(i).get(2));
  
            System.out.print(x + " ");
        }
        else
        {
            setElement(arr, n,
                       Q.get(i).get(1),
                       Q.get(i).get(2));
        }
    }
}
  
// Driver code
public static void main (String[] args)
{
    int arr[] = { 1, 2, 2, 3, 4, 4, 5, 6 };
    int n = arr.length;
     
    ArrayList<List<Integer>> Q = new ArrayList<>();
    Q.add(Arrays.asList(1, 3, 5));
    Q.add(Arrays.asList(1, 2, 4)); 
    Q.add(Arrays.asList(1, 1, 2));
    Q.add(Arrays.asList(2, 1, 7));
    Q.add(Arrays.asList(1, 1, 2));
     
    SolveQuery(arr, n, Q);
}
}
 
// This code is contributed by offbeat

Python3




# Python3 code for queries for number
# of elements that lie in range
# [l, r] (with updates)
from typing import Generic, List, TypeVar
 
T = TypeVar('T')
V = TypeVar('V')
 
class Pair(Generic[V, T]):
     
    def __init__(self, first: V, second: T) -> None:
         
        self.first = first
        self.second = second
 
# Function to set arr[index] = x
def setElement(arr: List[int], n: int,
                   index: int, x: int) -> None:
                        
    arr[index] = x
 
# Function to get count of elements
# that lie in range [l, r]
def getCount(arr: List[int], n: int,
                     l: int, r: int) -> int:
 
    count = 0
 
    # Traverse array
    for i in range(n):
 
        # If element lies in the
        # range [L, R]
        if (arr[i] >= l and arr[i] <= r):
 
            # Increase count
            count += 1
 
    return count
 
# Function to solve each query
def SolveQuery(arr: List[int], n: int,
            Q: List[Pair[int, Pair[int, int]]]):
 
    x = 0
 
    for i in range(len(Q)):
        if (Q[i].first == 1):
            x = getCount(arr, n, Q[i].second.first,
                                 Q[i].second.second)
            print(x, end = " ")
        else:
            setElement(arr, n, Q[i].second.first,
                               Q[i].second.second)
 
# Driver Code
if __name__ == "__main__":
 
    arr = [ 1, 2, 2, 3, 4, 4, 5, 6 ]
    n = len(arr)
 
    Q = [ Pair(1, Pair(3, 5)),
          Pair(1, Pair(2, 4)),
          Pair(1, Pair(1, 2)),
          Pair(2, Pair(1, 7)),
          Pair(1, Pair(1, 2)) ]
           
    SolveQuery(arr, n, Q)
 
# This code is contributed by sanjeev2552

C#




// C# code for queries for number
// of elements that lie in range
// [l, r] (with updates)
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to set arr[index] = x
static void setElement(int[] arr, int n,
                       int index, int x)
{
    arr[index] = x;
}
 
// Function to get count of elements
// that lie in range [l, r]
static int getCount(int[] arr, int n,
                    int l, int r)
{
    int count = 0;
     
    // Traverse array
    for(int i = 0; i < n; i++)
    {
         
        // If element lies in the
        // range [L, R]
        if (arr[i] >= l && arr[i] <= r)
         
            // Increase count
            count += 1;
    }
    return count;
}
 
// Function to solve each query
static void SolveQuery(int[] arr, int n,
             List<List<int>> Q)
{
    int x;
 
    for(int i = 0; i < Q.Count; i++)
    {
        if (Q[i][0] == 1)
        {
            x = getCount(arr, n,
                         Q[i][1],
                         Q[i][2]);
 
            Console.Write(x + " ");
        }
        else
        {
            setElement(arr, n,
                       Q[i][1],
                       Q[i][2]);
        }
    }
}
 
// Driver code
public static void Main(string[] args)
{
    int[] arr = { 1, 2, 2, 3, 4, 4, 5, 6 };
    int n = arr.Length;
 
    List<List<int>> myList = new List<List<int>>();
    myList.Add(new List<int>{ 1, 3, 5 });
    myList.Add(new List<int>{ 1, 2, 4 });
    myList.Add(new List<int>{ 1, 1, 2 });
    myList.Add(new List<int>{ 2, 1, 7 });
    myList.Add(new List<int>{ 1, 1, 2 });
 
    SolveQuery(arr, n, myList);
}
}
 
// This code is contributed by grand_master

Javascript




<script>
// Javascript code for queries for number
// of elements that lie in range
// [l, r] (with updates)
 
// Function to set arr[index] = x
function setElement(arr, n, index, x)
{
    arr[index] = x;
}
 
// Function to get count of elements
// that lie in range [l, r]
function getCount(arr, n, l, r)
{
    let count = 0;
 
    // Traverse array
    for (let i = 0; i < n; i++) {
 
        // If element lies in the
        // range [L, R]
        if (arr[i] >= l
            && arr[i] <= r) {
 
            // Increase count
            count++;
        }
    }
    return count;
}
 
// Function to solve each query
function SolveQuery(arr, n, Q) {
    let x;
 
    for (let i = 0; i < Q.length; i++) {
        if (Q[i][0] == 1) {
            x = getCount(arr, n,
                Q[i][1][0],
                Q[i][1][1]);
 
            document.write(x + " ");
        }
        else {
            setElement(arr, n,
                Q[i][1][0],
                Q[i][1][1]);
        }
    }
}
 
// Driver Code
let arr = [ 1, 2, 2, 3, 4, 4, 5, 6 ];
let n = arr.length;
 
let Q
    = [[1, [3, 5]],
    [1, [2, 4]],
    [1, [1, 2]],
    [2, [1, 7]],
    [1, [1, 2]]];
SolveQuery(arr, n, Q);
 
// This code is contributed by _saurabh_jaiswal.
</script>
Output: 
4 5 3 2

 

Time Complexity: O(Q * N) 
Auxiliary Space: O(1)

Efficient Approach: 
The above approach can be optimized using Fenwick Tree. Follow the steps below to solve the problem: 

  • Construct a Fenwick tree from the given array.
  • Fenwick tree will be represented as an array of size equal to maximum element in the array, so that the array elements can be used as index (idea is similar to this approach).
  • Traverse the array and increase the frequency of every element by calling the update method of Fenwick tree.
  • For each query of type (1 L R), call the getSum method of Fenwick tree. The answer for the query of type 1 will be:

getSum(R) – getSum(L – 1)

  • For each query of type (2 i x), call the update method of Fenwick tree to increase the frequency of the added element and decrease the count of the element to be replaced. 
     

Below is the implementation of the above approach:

C++




// C++ code for queries for number
// of elements that lie in range
// [l, r] (with updates)
#include <bits/stdc++.h>
using namespace std;
 
class FenwickTree {
public:
    int* BIT;
    int N;
 
    FenwickTree(int N)
    {
        this->N = N;
        BIT = new int[N];
        for (int i = 0; i < N; i++) {
            BIT[i] = 0;
        }
    }
 
    // Traverse all ancestors and
    // increase frequency of index
    void update(int index, int increment)
    {
        while (index < N) {
 
            // Increase count of the current
            // node of BIT Tree
            BIT[index] += increment;
 
            // Update index to that of parent
            // in update View
            index += (index & -index);
        }
    }
    // Function to return the
    // sum of arr[0..index]
    int getSum(int index)
    {
        int sum = 0;
 
        // Traverse ancestors of
        // BITree[index]
        while (index > 0) {
 
            // Add current element of
            // BITree to sum
            sum += BIT[index];
 
            // Move index to parent node in
            // getSum View
            index -= (index & -index);
        }
        return sum;
    }
};
 
// Function to set arr[index] = x
void setElement(int* arr, int n,
                int index, int x,
                FenwickTree* fenTree)
{
    int removedElement = arr[index];
    fenTree->update(removedElement, -1);
    arr[index] = x;
    fenTree->update(x, 1);
}
 
// Function to get count of
// elements that lie in
// range [l, r]
int getCount(int* arr, int n,
            int l, int r,
            FenwickTree* fenTree)
{
    int count = fenTree->getSum(r)
                - fenTree->getSum(l - 1);
    return count;
}
 
// Function to solve each query
void SolveQuery(int arr[], int n,
                vector<pair<int,
                            pair<int, int> > >
                    Q)
{
    int N = 100001;
 
    FenwickTree* fenTree = new FenwickTree(N);
 
    for (int i = 0; i < n; i++) {
        fenTree->update(arr[i], 1);
    }
 
    int x;
 
    for (int i = 0; i < Q.size(); i++) {
        if (Q[i].first == 1) {
            x = getCount(arr, n,
                        Q[i].second.first,
                        Q[i].second.second,
                        fenTree);
 
            cout << x << " ";
        }
        else {
            setElement(arr, n,
                    Q[i].second.first,
                    Q[i].second.second,
                    fenTree);
        }
    }
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 2, 2, 3,
                4, 4, 5, 6 };
 
    int n = sizeof(arr) / sizeof(arr[0]);
    vector<pair<int, pair<int, int> > > Q
        = { { 1, { 3, 5 } },
            { 1, { 2, 4 } },
            { 1, { 1, 2 } },
            { 2, { 1, 7 } },
            { 1, { 1, 2 } } };
 
    SolveQuery(arr, n, Q);
 
    return 0;
}
Output: 
4 5 3 2

 

Time Complexity: O(n*log(N) + Q*log(N)) 
Auxiliary Space: O(maxm), where maxm is the maximum element present in the array.
 




My Personal Notes arrow_drop_up
Recommended Articles
Page :