Counting values greater than equal to x after increments

Consider an array of size n with initial 0 values. How many indices will contain value at least x after performing m range updates. In each of the m queries you are given a range from L to R and you have to add 1 to each index starting from L to R (both inclusive). Now, you are given q queries and in each query, a number x. Your task is to find out how many array indices have value greater than or equal to x. (the value of n , m , q can be upto 10^6)

Examples :

Input :  n = 4
         l[] = {1, 1, 3};
         r[] = {3, 2, 4};         
         x[] = {1, 4, 2};
Output :
Number of indexes with atleat 1 is 4
Number of indexes with atleat 4 is 0
Number of indexes with atleat 2 is 3

Explanation :
Initial array is {0, 0, 0, 0}
After first update : {1, 1, 1, 0}
After second update : {2, 2, 1, 0}
After third update : {2, 2, 2, 1}

Naive Approach : The trivial solution that comes to mind is to create an array of size n and for each update [L,R] add 1 to each array index within this range. Then for each x, count by traversing the whole array, the number of indices with value greater than or equal to x . However, we are given that the value of n and q is very large (upto 10^6), so for every query we cannot simply traverse the array and find out how many indices have at-least x as their value. In the worst case time complexity is O(nq), which is quite inefficient.

Efficient Approach : The idea is to first compute values of array by accumulating all increments (We use same technique as this post). After finding elements, we find frequency of every element. Then we compute frequencies of greater elements by traversing from right to left. Finally, we can answer all queries in O(1) time.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ code to count element 
// with values at least x.
#include<bits/stdc++.h>
using namespace std;
  
// For every query in x[0..q-1], count of values
// greater than or equal to query value are printed.
void coutIndices(int n, int l[], int r[], int m,
                 int x[], int q)
{
    // Start and end store frequencies of all
    // starting and ending points
    int start[n+1] = {0};
    int End[n+1] = {0};
    for (int i = 0; i < m; i++)
    {
        start[l[i]] += 1;
        End[r[i]] += 1;
    }
  
    // Find actual array values after m queries
    int compute[n+1] = {0};
    compute[1] = start[1];
    for (int i = 1; i <= n; i++)
        compute[i] =  compute[i - 1] + start[i] -
                      End[i - 1];
  
    // Find frequency of every element in compute[]
    int max = *max_element(compute, compute+n+1);
    int freq[max+1] = {0};
    for (int i=1; i<=n; i++)
        freq[compute[i]]++;
  
    // reverse cumulative sum of the freq array
    // because of atleast value of array
    // indices for each possible x
    for (int i = max-1; i >= 0; i--)
        freq[i] += freq[i + 1];
  
    // Solving queries
    for (int i = 0; i < q; i++)
    {
        cout << "number of indexes with atleat " <<
             x[i] << " is ";
        if (x[i] > max)
            cout << 0 << "\n";
        else
            cout << freq[x[i]] << endl;
    }
}
  
// Driver code
int main()
{
    // Number of elements in an array
    // with all initial 0 values
    int n = 7;
  
    // Subarrays that need to be incremented
    int l[] = {1, 2, 1, 5};
    int r[] = {3, 5, 2, 6};
  
    // Query values
    int x[] = {1, 7, 4, 2};
  
    int m = sizeof(l)/sizeof(l[0]);
    int q = sizeof(x)/sizeof(x[0]);
    coutIndices(n, l, r, m, x, q);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java code to count element 
// with values at least x.
import java.io.*;
import java.util.*;
  
class GFG 
{
      
// For every query in x[0..q-1], 
// count of values greater than 
// or equal to query value are 
// printed.
static void coutIndices(int n, int l[], 
                        int r[], int m,
                        int x[], int q)
{
    // Start and end store 
    // frequencies of all 
    // starting and ending points
    int []start = new int[n + 1];
    int End[] = new int[n + 1];
      
    for (int i = 0; i < m; i++)
    {
        start[l[i]] += 1;
        End[r[i]] += 1;
    }
  
    // Find actual array 
    // values after m queries
    int compute[] = new int[n + 1];
    compute[1] = start[1];
    for (int i = 1; i <= n; i++)
        compute[i] = compute[i - 1] + 
                           start[i] -
                           End[i - 1];
  
    // Find frequency of every
    // element in compute[]
    Arrays.sort(compute);
    int max = compute[n];
    int freq[] = new int[max + 1];
      
    for (int i = 1; i <= n; i++)
        freq[compute[i]]++;
  
    // reverse cumulative sum of 
    // the freq array because of 
    // atleast value of array 
    // indices for each possible x
    for (int i = max - 1; i >= 0; i--)
        freq[i] += freq[i + 1];
  
    // Solving queries
    for (int i = 0; i < q; i++)
    {
        System.out.print("number of indexes "
                               "with atleat " +
                                x[i] + " is ");
        if (x[i] > max)
            System.out.println("0");
        else
            System.out.println(freq[x[i]]);
    }
}
  
// Driver code
public static void main (String[] args) 
{
      
// Number of elements in 
// an array with all 
// initial 0 values
int n = 7;
  
// Subarrays that need
// to be incremented
int l[] = {1, 2, 1, 5};
int r[] = {3, 5, 2, 6};
  
// Query values
int x[] = {1, 7, 4, 2};
  
int m = l.length;
int q = x.length;
coutIndices(n, l, r, m, x, q);
}
}
  
// This code has been 
// contributed by anuj_67.

chevron_right


Python3

# Python 3 code to count element with
# values at least x.

# For every query in x[0..q-1], count
# of values greater than or equal to
# query value are printed.
def coutIndices(n, l, r, m, x, q):

# Start and end store frequencies
# of all starting and ending points
start = [0 for i in range(n + 1)]
End = [0 for i in range(n + 1)]
for i in range(0, m, 1):
start[l[i]] += 1
End[r[i]] += 1

# Find actual array values
# after m queries
compute = [0 for i in range(n + 1)]
compute[1] = start[1]
for i in range(1, n + 1, 1):
compute[i] = (compute[i – 1] +
start[i] – End[i – 1])

# Find frequency of every
# element in compute[]
max = compute[0]
for i in range(len(compute)):
if(compute[i] > max):
max = compute[i]

freq = [0 for i in range(max + 1)]
for i in range(1, n + 1, 1):
freq[compute[i]] += 1

# reverse cumulative sum of the freq
# array because of atleast value of
# array indices for each possible x
i = max – 1
while(i >= 0):
freq[i] += freq[i + 1]
i -= 1

# Solving queries
for i in range(0, q, 1):
print(“number of indexes with atleat”,
x[i], “is”, end = ” “)
if (x[i] > max):
print(0)
else:
print(freq[x[i]])

# Driver code
if __name__ == ‘__main__’:

# Number of elements in an array
# with all initial 0 values
n = 7

# Subarrays that need to be incremented
l = [1, 2, 1, 5]
r = [3, 5, 2, 6]

# Query values
x= [1, 7, 4, 2]

m = len(l)
q = len(x)
coutIndices(n, l, r, m, x, q);

# This code is contributed by
# Sahil_Shelangia

C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# code to count element 
// with values at least x.
using System;
  
class GFG 
{
      
// For every query in x[0..q-1], 
// count of values greater than 
// or equal to query value are 
// printed.
static void coutIndices(int n, int []l, 
                        int []r, int m,
                        int []x, int q)
{
    // Start and end store 
    // frequencies of all 
    // starting and ending points
    int []start = new int[n + 1];
    int []End = new int[n + 1];
      
    for (int i = 0; i < m; i++)
    {
        start[l[i]] += 1;
        End[r[i]] += 1;
    }
  
    // Find actual array 
    // values after m queries
    int []compute = new int[n + 1];
    compute[1] = start[1];
    for (int i = 1; i <= n; i++)
        compute[i] = compute[i - 1] + 
                       start[i] -
                         End[i - 1];
  
    // Find frequency of every
    // element in compute[]
    Array.Sort(compute);
    int max = compute[n];
    int []freq = new int[max + 1];
      
    for (int i = 1; i <= n; i++)
        freq[compute[i]]++;
  
    // reverse cumulative sum of 
    // the freq array because of 
    // atleast value of array 
    // indices for each possible x
    for (int i = max - 1; i >= 0; i--)
        freq[i] += freq[i + 1];
  
    // Solving queries
    for (int i = 0; i < q; i++)
    {
        Console.Write("number of indexes "
                            "with atleat " +
                             x[i] + " is ");
        if (x[i] > max)
            Console.WriteLine("0");
        else
            Console.WriteLine(freq[x[i]]);
    }
}
  
// Driver code
public static void Main () 
{
      
// Number of elements in 
// an array with all 
// initial 0 values
int n = 7;
  
// Subarrays that need
// to be incremented
int []l = {1, 2, 1, 5};
int []r = {3, 5, 2, 6};
  
// Query values
int []x = {1, 7, 4, 2};
  
int m = l.Length;
int q = x.Length;
coutIndices(n, l, r, m, x, q);
}
}
  
// This code has been 
// contributed by anuj_67.

chevron_right


Output:

number of indexes with atleat 1 is 6
number of indexes with atleat 7 is 0
number of indexes with atleat 4 is 0
number of indexes with atleat 2 is 4


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : vt_m, sahilshelangia