Open In App

Queries for count of elements not present in range

Given an integer N which represents the total number of IDs present, a 2D array arr of size Mx2, where arr[i] = [ID, score] and 1D array query of size Q. We can assign multiple scores to a single ID. For each query q[i] where 0 <= i < Q, find the number of IDs who don’t have any scores within the range (query[i]/2, query[i]) where 0 <= i < Q.

Examples:



Input: N = 3, M = 4, arr[][] = [[1, 4], [2, 1], [1, 1], [3, 2]], query[] = [4, 2], Q =2
Output: [1, 0]
Explanation:

  • For the first query, its value is 4, so we have to find the number of IDs whose scores do not lie between [4/2, 4]. Seeing in arr[][], ID 1 and 3 have scores lying between range but score of ID 2 doesn’t. Therefore for first query, the answer is 1.
  • For the second query, its value is 2, so we have to find the number of IDs whose scores do not lie between [ 2/2, 2]. Seeing in arr[][] all IDs have scores lying between the range. Therefore for the second query, the answer is 0.

Input: N=2, M=4, arr[][] = [[2, 1], [1, 2], [1, 5], [2, 4]], query[] = [6, 10], Q = 2
Output: [0, 1]
Explanation:



  • For the first query, its value is 6, so we need to find the number of IDs whose scores do not lie between [6/2, 6]. Seeing in arr[][], all IDs have scores lying between the range. Therefore for the first query, answer is 0.
  • For the second query, its value is 10, so we need to find the number of IDs whose scores do not lie between [10/2, 10]. Seeing in arr[][], ID 1 has scores lying between the range but scores of ID 2 doesn’t. Therefore, for the second query, the answer is 1.

Approach: This can be solved with the following idea:

This can be solved by using a map as frequency array and two pointers algorithm. Instead of solving the queries in order of the input we can sort the queries and solve using two pointers. Sort the query and arr. For each query we try to maintain 2 pointers (start and end) which will maintain a window of only those scores (with IDs) which lie inside the query range. To get the answer of a query, we simply subtract the total number of IDs present (N) – IDs having values within the query range.

Below are the steps involved in the implementation of the code:

Below is the implementation of the following code:




// C++ Implementation
#include <bits/stdc++.h>
using namespace std;
 
// Function to count number of elements
// not in specified range
void count(int n, vector<vector<int> >& arr,
           vector<int>& query)
{
    // vector to store the score with their IDs
    vector<pair<int, int> > vp;
    for (int i = 0; i < arr.size(); i++) {
        vp.push_back({ arr[i][1], arr[i][0] });
    }
    // vector to store the order of input queries
    vector<pair<int, int> > vq;
    int q = query.size();
    for (int i = 0; i < q; i++) {
        vq.push_back({ query[i], i });
    }
    sort(vp.begin(), vp.end());
    sort(vq.begin(), vq.end());
 
    // map to store the frequency of IDs
    map<int, int> freq;
    vector<int> ans(q);
    int l = 0, r = 0;
    for (int i = 0; i < q; i++) {
        int query_number = vq[i].second;
        int start = vq[i].first / 2;
        int end = vq[i].first;
 
        while (r < vp.size() && vp[r].first <= end) {
            freq[vp[r].second]++;
            r++;
        }
 
        while (l < vp.size() && vp[l].first < start) {
            freq[vp[l].second]--;
            if (freq[vp[l].second] == 0)
                freq.erase(vp[l].second);
            l++;
        }
        ans[query_number] = n - freq.size();
    }
 
    for (int i = 0; i < q; i++)
        cout << ans[i] << " ";
    cout << "\n";
}
 
// Driver code
int main()
{
    int N = 3;
 
    vector<vector<int> > arr
        = { { 1, 4 }, { 2, 1 }, { 1, 1 }, { 3, 2 } };
 
    vector<int> query = { 4, 2 };
 
    // Function call
    count(N, arr, query);
 
    return 0;
}




// Java Implementation
import java.util.*;
 
public class Main {
    // Function to count number of elements not in specified range
    public static void count(int n, List<List<Integer>> arr, List<Integer> query) {
        // ArrayList to store the score with their IDs
        List<Pair<Integer, Integer>> vp = new ArrayList<>();
        for (List<Integer> list : arr) {
            vp.add(new Pair<>(list.get(1), list.get(0)));
        }
 
        // ArrayList to store the order of input queries
        List<Pair<Integer, Integer>> vq = new ArrayList<>();
        int q = query.size();
        for (int i = 0; i < q; i++) {
            vq.add(new Pair<>(query.get(i), i));
        }
 
        // Sort both ArrayLists based on the first element
        Collections.sort(vp, Comparator.comparingInt(o -> o.getKey()));
        Collections.sort(vq, Comparator.comparingInt(Pair::getKey));
 
        // HashMap to store the frequency of IDs
        Map<Integer, Integer> freq = new HashMap<>();
        int[] ans = new int[q];
        int l = 0, r = 0;
        for (int i = 0; i < q; i++) {
            int queryNumber = vq.get(i).getValue();
            int start = vq.get(i).getKey() / 2;
            int end = vq.get(i).getKey();
 
            while (r < vp.size() && vp.get(r).getKey() <= end) {
                freq.put(vp.get(r).getValue(), freq.getOrDefault(vp.get(r).getValue(), 0) + 1);
                r++;
            }
 
            while (l < vp.size() && vp.get(l).getKey() < start) {
                freq.put(vp.get(l).getValue(), freq.get(vp.get(l).getValue()) - 1);
                if (freq.get(vp.get(l).getValue()) == 0) {
                    freq.remove(vp.get(l).getValue());
                }
                l++;
            }
            ans[queryNumber] = n - freq.size();
        }
 
        // Print the result
        for (int i = 0; i < q; i++) {
            System.out.print(ans[i] + " ");
        }
        System.out.println();
    }
 
    public static void main(String[] args) {
        int N = 3;
 
        List<List<Integer>> arr = Arrays.asList(
            Arrays.asList(1, 4),
            Arrays.asList(2, 1),
            Arrays.asList(1, 1),
            Arrays.asList(3, 2)
        );
 
        List<Integer> query = Arrays.asList(4, 2);
 
        // Function call
        count(N, arr, query);
    }
 
    // Helper class to store pairs
    static class Pair<K, V> {
        private final K key;
        private final V value;
 
        public Pair(K key, V value) {
            this.key = key;
            this.value = value;
        }
 
        public K getKey() {
            return key;
        }
 
        public V getValue() {
            return value;
        }
    }
}
// This code is contributed by Tapesh(tapeshdua420)




from collections import defaultdict
 
# Function to count number of elements not in specified range
def count(n, arr, query):
    # List to store the score with their IDs
    vp = [(arr[i][1], arr[i][0]) for i in range(len(arr))]
     
    # List to store the order of input queries
    vq = [(query[i], i) for i in range(len(query))]
     
    vp.sort()
    vq.sort()
 
    # Dictionary to store the frequency of IDs
    freq = defaultdict(int)
    ans = [0] * len(query)
    l = 0
    r = 0
     
    for i in range(len(query)):
        query_number = vq[i][1]
        start = vq[i][0] // 2
        end = vq[i][0]
 
        while r < len(vp) and vp[r][0] <= end:
            freq[vp[r][1]] += 1
            r += 1
 
        while l < len(vp) and vp[l][0] < start:
            freq[vp[l][1]] -= 1
            if freq[vp[l][1]] == 0:
                del freq[vp[l][1]]
            l += 1
 
        ans[query_number] = n - len(freq)
 
    for i in range(len(query)):
        print(ans[i], end=" ")
 
# Driver code
if __name__ == "__main__":
    N = 3
 
    arr = [[1, 4], [2, 1], [1, 1], [3, 2]]
 
    query = [4, 2]
 
    # Function call
    count(N, arr, query)




// C# program for the above approach
using System;
using System.Collections.Generic;
using System.Linq;
 
public class GFG {
    // Function to count the number of elements
    // not in the specified range
    static void Count(int n, List<List<int> > arr,
                      List<int> query)
    {
        // List to store the score with their IDs
        List<Tuple<int, int> > vp
            = new List<Tuple<int, int> >();
        for (int i = 0; i < arr.Count; i++) {
            vp.Add(
                new Tuple<int, int>(arr[i][1], arr[i][0]));
        }
 
        // List to store the order of input queries
        List<Tuple<int, int> > vq
            = new List<Tuple<int, int> >();
        int q = query.Count;
        for (int i = 0; i < q; i++) {
            vq.Add(new Tuple<int, int>(query[i], i));
        }
 
        vp.Sort();
        vq.Sort();
 
        // Dictionary to store the frequency of IDs
        Dictionary<int, int> freq
            = new Dictionary<int, int>();
        List<int> ans = new List<int>(new int[q]);
 
        int l = 0, r = 0;
 
        for (int i = 0; i < q; i++) {
            int queryNumber = vq[i].Item2;
            int start = vq[i].Item1 / 2;
            int end = vq[i].Item1;
 
            while (r < vp.Count && vp[r].Item1 <= end) {
                if (!freq.ContainsKey(vp[r].Item2)) {
                    freq[vp[r].Item2] = 0;
                }
                freq[vp[r].Item2]++;
                r++;
            }
 
            while (l < vp.Count && vp[l].Item1 < start) {
                freq[vp[l].Item2]--;
                if (freq[vp[l].Item2] == 0) {
                    freq.Remove(vp[l].Item2);
                }
                l++;
            }
 
            ans[queryNumber] = n - freq.Count;
        }
 
        Console.WriteLine(string.Join(" ", ans));
    }
 
    // Driver code
    static void Main()
    {
        int N = 3;
 
        List<List<int> > arr = new List<List<int> >{
            new List<int>{ 1, 4 }, new List<int>{ 2, 1 },
            new List<int>{ 1, 1 }, new List<int>{ 3, 2 }
        };
 
        List<int> query = new List<int>{ 4, 2 };
 
        // Function call
        Count(N, arr, query);
    }
}
 
// This code is contributed by Susobhan Akhuli




// JavaScript program for the above approach
 
// Function to count number of elements
// not in the specified range
function count(n, arr, query) {
    // Array to store the score with their IDs
    let vp = [];
    for (let i = 0; i < arr.length; i++) {
        vp.push([arr[i][1], arr[i][0]]);
    }
 
    // Array to store the order of input queries
    let vq = [];
    let q = query.length;
    for (let i = 0; i < q; i++) {
        vq.push([query[i], i]);
    }
 
    vp.sort((a, b) => a[0] - b[0]);
    vq.sort((a, b) => a[0] - b[0]);
 
    // Map to store the frequency of IDs
    let freq = new Map();
    let ans = Array(q).fill(0);
    let l = 0, r = 0;
 
    for (let i = 0; i < q; i++) {
        let queryNumber = vq[i][1];
        let start = Math.floor(vq[i][0] / 2);
        let end = vq[i][0];
 
        while (r < vp.length && vp[r][0] <= end) {
            freq.set(vp[r][1], (freq.get(vp[r][1]) || 0) + 1);
            r++;
        }
 
        while (l < vp.length && vp[l][0] < start) {
            freq.set(vp[l][1], freq.get(vp[l][1]) - 1);
            if (freq.get(vp[l][1]) === 0) {
                freq.delete(vp[l][1]);
            }
            l++;
        }
 
        ans[queryNumber] = n - freq.size;
    }
 
    console.log(ans.join(" "));
}
 
// Driver code
let N = 3;
 
let arr = [
    [1, 4],
    [2, 1],
    [1, 1],
    [3, 2]
];
 
let query = [4, 2];
 
// Function call
count(N, arr, query);
 
// This code is contributed by Susobhan Akhuli

Output
1 0 






Complexity Analysis:
Time Complexity: O(M log M + Q log Q )
Auxiliary Space: O(M + Q)
where M is the size of 2D array arr, and Q is the number of queries


Article Tags :