# Count of locations between X and Y having rainfall more than K cms for Q queries

• Difficulty Level : Hard
• Last Updated : 18 Apr, 2022

Given an array arr[][] consisting of N triplets ( start, end, rainfall in cms), defining rain will fall from the start location to the end location with the given intensity of rainfall in cms. Also given an integer K and Q queries in the form of array query[][] ( In each query X and Y is given ). For each query, the task is to find the number of locations between X and Y ( inclusive ) having rainfall more than K cms.

Examples:

Input: arr[][] = {{1, 3, 5}, {2, 8, 3}, {5, 8, 2}, {7, 9, 6}}, K = 5, query[][] ={{1, 5}, {5, 9}, {2, 9}, {1, 9}}
Output: 4, 5, 7, 8
Explanation: The aggregate array for given locations will be:

The aggregate array tells about the amount of rainfall in each location.

From locations 1 to 5, { 1, 2, 3, 5 } have rainfall  >= 5 cms, Therefore answer is 4.
From locations 5 to 9, { 5, 6, 7, 8, 9 } have rainfall  >= 5 cms, Therefore answer is 5.
From locations 2 to 9, { 2, 3, 5, 6, 7, 8, 9 } have rainfall  >= 5 cms, Therefore answer is 7.
From locations 1 to 9, { 1, 2, 3, 5, 6, 7, 8, 9 } have rainfall  >= 5 cms, Therefore answer is 9.

Input: arr[][] = {{2, 4, 1 }, {3, 9, 3}}, K = 5, query[][] ={{2, 5}, {4, 6}}
Output: 3, 3

Naive approach: Traverse array arr[][] and find the maximum value of location. Create an array with size equals to the maximum location found. Then for each range of rainfall update the array to get the aggregated array. Now for each query traverse the formed array and count the number of locations with rainfall greater than K cms.

Below is the code for the above approach.

## C++

 `// C++ program for above approach``#include ``using` `namespace` `std;` `// Function to find number of locations``// with rainfall  more than K cms``vector<``int``> count(vector<``int``> arr, vector > Q,``                  ``int` `q, ``int` `k)``{``    ``vector<``int``> ans;``    ``for` `(``int` `i = 0; i < q; i++) {``        ``int` `temp = 0;``        ``for` `(``int` `j = Q[i]; j <= Q[i]; j++) {``            ``if` `(arr[j] >= k)``                ``temp++;``        ``}``        ``ans.push_back(temp);``    ``}``    ``return` `ans;``}` `// Function to find aggregate array``vector<``int``> aggregateArray(vector > arr, ``int` `n)``{``    ``// To store the maximum location``    ``int` `m = 0;` `    ``for` `(``int` `i = 0; i < n; i++)``        ``m = max(m, arr[i]);` `    ``// Array to store the aggregate values``    ``vector<``int``> agg(m + 1);``    ``for` `(``int` `i = 0; i < n; i++) {``        ``for` `(``int` `j = arr[i]; j <= arr[i]; j++) {``            ``agg[j] += arr[i];``        ``}``    ``}``    ``return` `agg;``}` `// Driver Code``int` `main()``{``    ``int` `N = 4;``    ``vector > arr = {``        ``{ 1, 3, 5 }, { 2, 8, 3 }, { 5, 8, 2 }, { 7, 9, 6 }``    ``};` `    ``// Storing aggregate array``    ``vector<``int``> agg = aggregateArray(arr, N);` `    ``int` `Q = 4;``    ``vector > queries``        ``= { { 1, 5 }, { 5, 9 }, { 2, 9 }, { 1, 9 } };``    ``int` `K = 5;``    ``vector<``int``> ans = count(agg, queries, Q, K);` `    ``// Printing answer to each query``    ``for` `(``int` `i = 0; i < N; i++) {``        ``cout << ans[i] << endl;``    ``}``}`

## Java

 `// Java program for above approach``public` `class` `GFG {` `  ``// Function to find number of locations``  ``// with rainfall  more than K cms``  ``static` `int``[] count(``int` `arr[], ``int` `Q[][], ``int` `q, ``int` `k)``  ``{``    ``int` `ans[] = ``new` `int``[q];``    ``for` `(``int` `i = ``0``; i < q; i++) {``      ``int` `temp = ``0``;``      ``for` `(``int` `j = Q[i][``0``]; j <= Q[i][``1``]; j++) {``        ``if` `(arr[j] >= k)``          ``temp++;``      ``}``      ``ans[i] = temp;``    ``}``    ``return` `ans;``  ``}` `  ``// Function to find aggregate array``  ``static` `int``[] aggregateArray(``int` `arr[][], ``int` `n)``  ``{``    ``// To store the maximum location``    ``int` `m = ``0``;` `    ``for` `(``int` `i = ``0``; i < n; i++)``      ``m = Math.max(m, arr[i][``1``]);` `    ``// Array to store the aggregate values``    ``int` `agg[] = ``new` `int``[m + ``1``];``    ``for` `(``int` `i = ``0``; i < n; i++) {``      ``for` `(``int` `j = arr[i][``0``]; j <= arr[i][``1``]; j++) {``        ``agg[j] += arr[i][``2``];``      ``}``    ``}``    ``return` `agg;``  ``}` `  ``// Driver code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int` `N = ``4``;``    ``int` `arr[][] = { { ``1``, ``3``, ``5` `},``                   ``{ ``2``, ``8``, ``3` `},``                   ``{ ``5``, ``8``, ``2` `},``                   ``{ ``7``, ``9``, ``6` `} };` `    ``// Storing aggregate array``    ``int` `agg[] = aggregateArray(arr, N);` `    ``int` `Q = ``4``;``    ``int` `queries[][]``      ``= { { ``1``, ``5` `}, { ``5``, ``9` `}, { ``2``, ``9` `}, { ``1``, ``9` `} };``    ``int` `K = ``5``;``    ``int` `ans[] = count(agg, queries, Q, K);` `    ``// Printing answer to each query``    ``for` `(``int` `i = ``0``; i < N; i++) {``      ``System.out.println(ans[i]);``    ``}``  ``}``}` `// This code is contributed by phasing17`

## Python3

 `# python program for above approach` `# Function to find number of locations``# with rainfall more than K cms`  `def` `count(arr, Q, q, k):` `    ``ans ``=` `[]``    ``for` `i ``in` `range``(``0``, q):``        ``temp ``=` `0``        ``for` `j ``in` `range``(Q[i][``0``], Q[i][``1``] ``+` `1``):``            ``if` `(arr[j] >``=` `k):``                ``temp ``+``=` `1` `        ``ans.append(temp)` `    ``return` `ans`  `# Function to find aggregate array``def` `aggregateArray(arr, n):` `    ``# To store the maximum location``    ``m ``=` `0` `    ``for` `i ``in` `range``(``0``, n):``        ``m ``=` `max``(m, arr[i][``1``])` `    ``# Array to store the aggregate values``    ``agg ``=` `[``0` `for` `_ ``in` `range``(m ``+` `1``)]``    ``for` `i ``in` `range``(``0``, n):``        ``for` `j ``in` `range``(arr[i][``0``], arr[i][``1``] ``+` `1``):``            ``agg[j] ``+``=` `arr[i][``2``]` `    ``return` `agg`  `# Driver Code``if` `__name__ ``=``=` `"__main__"``:` `    ``N ``=` `4``    ``arr ``=` `[``        ``[``1``, ``3``, ``5``], [``2``, ``8``, ``3``],``        ``[``5``, ``8``, ``2``], [``7``, ``9``, ``6``]``    ``]` `    ``# Storing aggregate array``    ``agg ``=` `aggregateArray(arr, N)` `    ``Q ``=` `4``    ``queries ``=` `[[``1``, ``5``], [``5``, ``9``],``               ``[``2``, ``9``], [``1``, ``9``]]` `    ``K ``=` `5``    ``ans ``=` `count(agg, queries, Q, K)` `    ``# Printing answer to each query``    ``for` `i ``in` `range``(``0``, N):``        ``print``(ans[i])` `    ``# This code is contributed by rakeshsahni`

## Javascript

 ``
Output
```4
5
7
8```

Time Complexity: O(max(O(N*M), O(Q*M))).
Auxiliary space: O(M).
Where N is number of inputs, Q is number of queries, and M is max location.

Efficient Approach: The given problem can be solved by using the Weighted job scheduling approach and with Prefix Sum. This problem can be solved in two parts, forming aggregated array and then apply prefix sum for answering queries efficiently. Follow the steps below to solve the given problem.

• Sort arr[][] on the basis of end location.
• Use map data structure to store the start location and overlap count.
• For each end location, update the aggregate array, by doing rainfall data + overlap.
• Use Hashmaps for decrementing overlap, after the start location is crossed.
• For each triplet update the Hashmap with the start time.
• Traverse and fill overlap in the array until the end location of the next triplet is reached.
• Once the aggregate array is found, use prefix sum to find the answer to each query.

Below is the implementation of the above approach:

## C++

 `// C++ program for above approach``#include ``using` `namespace` `std;` `// Comparator function to sort``// the array in specific order``static` `bool` `comp(vector<``int``> a, vector<``int``> b)``{``    ``return` `(a > b);``}` `// Function to find number of locations``// with rainfall  more than K cms``vector<``int``> count(vector<``int``> arr, vector > Q,``                  ``int` `q, ``int` `k)``{` `    ``// Prefix sum array,``    ``// of count of locations having``    ``// rainfall greater than k cms``    ``int` `n = arr.size();``    ``vector<``int``> arrPre(n);` `    ``if` `(arr >= k)``        ``arrPre = 1;``    ``else``        ``arrPre = 0;` `    ``for` `(``int` `i = 1; i < n; i++) {` `        ``if` `(arr[i] >= k)``            ``arrPre[i] = arrPre[i - 1] + 1;` `        ``else``            ``arrPre[i] = arrPre[i - 1];``    ``}` `    ``// evaluating the queries``    ``vector<``int``> ans;``    ``for` `(``int` `i = 0; i < q; i++) {``        ``ans.push_back(arrPre[Q[i]]``                      ``- arrPre[Q[i] - 1]);``    ``}``    ``return` `ans;``}` `// Function to find aggregate array``vector<``int``> aggregateArray(vector > N, ``int` `n)``{``    ``// To store the maximum location``    ``int` `m = 0;``    ``for` `(``int` `i = 0; i < n; i++)``        ``m = max(m, N[i]);` `    ``// Array to store rainfall``    ``// of m locations sorting``    ``// input array based on end time,``    ``// in descending order``    ``vector<``int``> arr(m + 1);``    ``sort(N.begin(), N.end(), comp);` `    ``// To store start locn and``    ``// rainfall corresponding to it``    ``unordered_map<``int``, ``int``> start;``    ``int` `overlap = 0;` `    ``for` `(``int` `i = 0; i < n; i++) {``        ``// If two inputs have same end time,``        ``// we need to reposition them``        ``if` `(m < N[i])``            ``m++;``        ``else``            ``// Fill m with overlap,``            ``// till we reach current end location,``            ``// and keep checking if we've crossed``            ``// start time of previously recorded data``            ``// and decrement overlap(map)``            ``while` `(m > 0 && m != N[i])``                ``overlap -= start[m], arr[m--] = overlap;` `        ``// To check if start time is crossed``        ``// of previously recorded data``        ``// and decrement overlap(map)``        ``overlap -= start[m];` `        ``// Input data + previous recorded data``        ``arr[m] = overlap + N[i];` `        ``// updating overlap with current data``        ``overlap += N[i];` `        ``// storing start location with``        ``// corresponding rainfall data``        ``start[N[i] - 1] = N[i];` `        ``// update m``        ``m--;``    ``}``    ``while` `(m >= N[n - 1])` `        ``// fill out the left out indexes``        ``overlap -= start[m], arr[m--] = overlap;``    ``return` `arr;``}` `// Driver Code``int` `main()``{``    ``int` `N = 4;``    ``vector > arr = {``        ``{ 1, 3, 5 }, { 2, 8, 3 }, { 5, 8, 2 }, { 7, 9, 6 }``    ``};``    ``vector<``int``> agg = aggregateArray(arr, N);` `    ``int` `Q = 4;` `    ``vector > queries``        ``= { { 1, 5 }, { 5, 9 }, { 2, 9 }, { 1, 9 } };``    ``int` `K = 5;``    ``vector<``int``> ans = count(agg, queries, Q, K);` `    ``// Printing answer to each query``    ``for` `(``int` `i = 0; i < N; i++) {``        ``cout << ans[i] << endl;``    ``}``}`

## Python3

 `# Python program for above approach` `# Function to find number of locations``# with rainfall  more than K cms``from` `functools ``import` `cmp_to_key` `def` `mycmp(a, b):``    ``return` `b[``1``] ``-` `a[``1``]` `def` `count(arr, Q, q, k):` `    ``# Prefix sum array,``    ``# of count of locations having``    ``# rainfall greater than k cms``    ``n ``=` `len``(arr)``    ``arrPre ``=` `[``0` `for` `i ``in` `range``(n)]` `    ``if` `(arr[``0``] >``=` `k):``        ``arrPre[``0``] ``=` `1``    ``else``:``        ``arrPre[``0``] ``=` `0` `    ``for` `i ``in` `range``(``1``,n):` `        ``if` `(arr[i] >``=` `k):``            ``arrPre[i] ``=` `arrPre[i ``-` `1``] ``+` `1` `        ``else``:``            ``arrPre[i] ``=` `arrPre[i ``-` `1``]` `    ``# evaluating the queries``    ``ans ``=` `[]``    ``for` `i ``in` `range``(q):``        ``ans.append(arrPre[Q[i][``1``]] ``-` `arrPre[Q[i][``0``] ``-` `1``])``    ` `    ``return` `ans` `# Function to find aggregate array``def` `aggregateArray(N, n):` `    ``# To store the maximum location``    ``m ``=` `0``    ``for` `i ``in` `range``(n):``        ``m ``=` `max``(m, N[i][``1``])` `    ``# Array to store rainfall``    ``# of m locations sorting``    ``# input array based on end time,``    ``# in descending order``    ``arr ``=` `[``0` `for` `i ``in` `range``(m``+``1``)]``    ``N.sort(key ``=` `cmp_to_key(mycmp))` `    ``# To store start locn and``    ``# rainfall corresponding to it``    ``start ``=` `{}``    ``overlap ``=` `0` `    ``for` `i ``in` `range``(n):``        ``# If two inputs have same end time,``        ``# we need to reposition them``        ``if` `(m < N[i][``1``]):``            ``m ``+``=` `1``        ``else``:``            ``# Fill m with overlap,``            ``# till we reach current end location,``            ``# and keep checking if we've crossed``            ``# start time of previously recorded data``            ``# and decreament overlap(map)``            ``while` `(m > ``0` `and` `m !``=` `N[i][``1``]):``                ``overlap ``-``=` `start[m] ``if` `m ``in` `start ``else` `0``                ``arr[m] ``=` `overlap``                ``m ``-``=` `1` `        ``# To check if start time is crossed``        ``# of previously recorded data``        ``# and decreament overlap(map)``        ``overlap ``-``=` `start[m] ``if` `m ``in` `start ``else` `0` `        ``# Input data + previous recorded data``        ``arr[m] ``=` `overlap ``+` `N[i][``2``]` `        ``# updating overlap with current data``        ``overlap ``+``=` `N[i][``2``]` `        ``# storing start location with``        ``# corresponding rainfall data``        ``start[N[i][``0``] ``-` `1``] ``=` `N[i][``2``]` `        ``# update m``        ``m ``-``=` `1` `    ``while` `(m >``=` `N[n ``-` `1``][``0``]):``        ``# fill out the left out indexes``        ``overlap ``-``=`  `start[m] ``if` `m ``in` `start ``else` `0``        ``arr[m] ``=` `overlap``        ``m ``-``=` `1` `    ``return` `arr` `# Driver Code``N ``=` `4``arr ``=` `[``    ``[ ``1``, ``3``, ``5` `], [ ``2``, ``8``, ``3` `],``    ``[ ``5``, ``8``, ``2` `], [ ``7``, ``9``, ``6` `]``]``agg ``=` `aggregateArray(arr, N)``Q ``=` `4``queries ``=` `[ [ ``1``, ``5` `], [ ``5``, ``9` `],``        ``[ ``2``, ``9` `], [ ``1``, ``9` `] ]``K ``=` `5``ans ``=` `count(agg, queries, Q, K)` `# Printing answer to each query``for` `i ``in` `range``(N):``    ``print``(ans[i])` `# This code is contributed by shinjanpatra`

## Javascript

 ``
Output
```4
5
7
8```

Time Complexity: O(max(NlogN, M)).
Auxiliary Space: O(M).
Where N is number of inputs and M is maximum location.

Efficient Approach 2: In the above approach, we are first sorting the array on the basis of end time and then calculating the aggregate array which takes O(NLogN) time. We can improve this time by calculating the aggregate array as follows:

Let the aggregate array be agg[].

We first iterate over each of the rainfall data. For each data (start, end, and val), add val to agg[start] and subtract val from agg[end+1] because the rainfall starts from position start and continue till end (inclusive). Then, we iterate second time over the agg array and keep track of current rainfall currRain (initialized to 0) by adding the value of agg[index] to it and updating agg[index] as currRain. Once the aggregate array is created, use prefix sum to find the answer each query.

Below is the implementation of the above approach:

## Python3

 `# Python3 program for above approach` `# Function to find number of locations with rainfall more than K cms``def` `count(arr, Q, q, k):``    ``n ``=` `len``(arr)` `    ``# prefix sum array``    ``prefix ``=` `[``0` `for` `_ ``in` `range``(n)]``    ``if` `arr[``0``] >``=` `k:``        ``prefix[``0``] ``=` `1``    ``else``:``        ``prefix[``0``] ``=` `0` `    ``for` `i ``in` `range``(``1``, n``-``1``):``        ``if` `arr[i] >``=` `k:``            ``prefix[i] ``=` `prefix[i``-``1``] ``+` `1``        ``else``:``            ``prefix[i] ``=` `prefix[i``-``1``]` `    ``# evaluate the queries using prefix sum array``    ``ans ``=` `[]``    ``for` `i ``in` `range``(``0``, q):``        ``start, end ``=` `Q[i][``0``]``-``1``, Q[i][``1``]``-``1` `        ``# if start is the minimum location possible, store prefix[end]``        ``if` `start ``=``=` `0``:``            ``count ``=` `prefix[end]``        ``else``:``            ``count ``=` `prefix[end] ``-` `prefix[start``-``1``]``            ` `        ``ans.append(count)` `    ``return` `ans` `# Function to find aggregate array``def` `aggregateArray(arr, n):` `    ``# find maximum location possible``    ``m ``=` `-``1``    ``for` `data ``in` `arr:``        ``m ``=` `max``(m, data[``1``])` `    ``# Array to store the aggregate values``    ``agg ``=` `[``0` `for` `_ ``in` `range``(m ``+` `1``)]` `    ``# update aggregate array at index start-1 and end locations``    ``for` `start, end, val ``in` `arr:``        ``agg[start``-``1``] ``+``=` `val``        ``agg[end] ``-``=` `val` `    ``# iterate second time to fill the complete aggregate array``    ``# currRain holds amount of rainfall till current index``    ``currRain ``=` `0``    ``for` `i ``in` `range``(m``+``1``):``        ``currRain ``+``=` `agg[i]``        ``agg[i] ``=` `currRain` `    ``return` `agg` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:``    ``N ``=` `4``    ``arr ``=` `[``    ``[``1``, ``3``, ``5``], [``2``, ``8``, ``3``],``    ``[``5``, ``8``, ``2``], [``7``, ``9``, ``6``]``    ``]` `    ``# Storing aggregate array``    ``agg ``=` `aggregateArray(arr, N)` `    ``Q ``=` `4``    ``queries ``=` `[[``1``, ``5``], [``5``, ``9``],``    ``[``2``, ``9``], [``1``, ``9``]]` `    ``K ``=` `5``    ``ans ``=` `count(agg, queries, Q, K)` `    ``# Printing answer to each query``    ``for` `i ``in` `range``(``0``, N):``        ``print``(ans[i])` `# This code is contributed by ultrainstinct`
Output
```4
5
7
8```

Time Complexity: O(M).

Auxiliary Space: O(M).

Where M is maximum location.

My Personal Notes arrow_drop_up