Queries for number of distinct elements in a subarray

23 Mar, 2022
Given a array ‘a[]’ of size n and number of queries q. Each query can be represented by two integers l and r. Your task is to print the number of distinct integers in the subarray l to r. Given a[i] <= 106 Examples:
Input : a[] = {1, 1, 2, 1, 3}
        q = 3
        0 4
        1 3
        2 4
Output :3
        2
        3
In query 1, number of distinct integers
in a[0...4] is 3 (1, 2, 3)
In query 2, number of distinct integers 
in a[1..3] is 2 (1, 2)
In query 3, number of distinct integers 
in a[2..4] is 3 (1, 2, 3)
The idea is to use Binary Indexed Tree 
Step 1 : Take an array last_visit of size 10^6 where last_visit[i] holds the rightmost index of the number i in the array a. Initialize this array as -1.Step 2 : Sort all the queries in ascending order of their right end r.Step 3 : Create a Binary Indexed Tree in an array bit[]. Start traversing the array ‘a’ and queries simultaneously and check if last_visit[a[i]] is -1 or not. If it is not, update the bit array with value -1 at the idx last_visit[a[i]].Step 4 : Set last_visit[a[i]] = i and update the bit array bit array with value 1 at idx i.Step 5 : Answer all the queries whose value of r is equal to i by querying the bit array. This can be easily done as queries are sorted.
Step 1 : Take an array last_visit of size 10^6 where last_visit[i] holds the rightmost index of the number i in the array a. Initialize this array as -1.
Step 2 : Sort all the queries in ascending order of their right end r.
Step 3 : Create a Binary Indexed Tree in an array bit[]. Start traversing the array ‘a’ and queries simultaneously and check if last_visit[a[i]] is -1 or not. If it is not, update the bit array with value -1 at the idx last_visit[a[i]].
Step 4 : Set last_visit[a[i]] = i and update the bit array bit array with value 1 at idx i.
Step 5 : Answer all the queries whose value of r is equal to i by querying the bit array. This can be easily done as queries are sorted.
C++
Java
Python3
Javascript
// C++ code to find number of distinct numbers// in a subarray#include<bits/stdc++.h>using namespace std; const int MAX = 1000001; // structure to store queriesstruct Query{    int l, r, idx;}; // cmp function to sort queries according to rbool cmp(Query x, Query y){    return x.r < y.r;} // updating the bit arrayvoid update(int idx, int val, int bit[], int n){    for (; idx <= n; idx += idx&-idx)        bit[idx] += val;} // querying the bit arrayint query(int idx, int bit[], int n){    int sum = 0;    for (; idx>0; idx-=idx&-idx)        sum += bit[idx];    return sum;} void answeringQueries(int arr[], int n, Query queries[], int q){    // initialising bit array    int bit[n+1];    memset(bit, 0, sizeof(bit));     // holds the rightmost index of any number    // as numbers of a[i] are less than or equal to 10^6    int last_visit[MAX];    memset(last_visit, -1, sizeof(last_visit));     // answer for each query    int ans[q];    int query_counter = 0;    for (int i=0; i<n; i++)    {        // If last visit is not -1 update -1 at the        // idx equal to last_visit[arr[i]]        if (last_visit[arr[i]] !=-1)            update (last_visit[arr[i]] + 1, -1, bit, n);         // Setting last_visit[arr[i]] as i and updating        // the bit array accordingly        last_visit[arr[i]] = i;        update(i + 1, 1, bit, n);         // If i is equal to r of any query  store answer        // for that query in ans[]        while (query_counter < q && queries[query_counter].r == i)        {            ans[queries[query_counter].idx] =                     query(queries[query_counter].r + 1, bit, n)-                     query(queries[query_counter].l, bit, n);            query_counter++;        }    }     // print answer for each query    for (int i=0; i<q; i++)        cout << ans[i] << endl;} // driver codeint main(){    int a[] = {1, 1, 2, 1, 3};    int n = sizeof(a)/sizeof(a[0]);    Query queries[3];    queries[0].l = 0;    queries[0].r = 4;    queries[0].idx = 0;    queries[1].l = 1;    queries[1].r = 3;    queries[1].idx = 1;    queries[2].l = 2;    queries[2].r = 4;    queries[2].idx = 2;    int q = sizeof(queries)/sizeof(queries[0]);    sort(queries, queries+q, cmp);    answeringQueries(a, n, queries, q);    return 0;}
// Java code to find number of distinct numbers// in a subarrayimport java.io.*;import java.util.*; class GFG{    static int MAX = 1000001;     // structure to store queries    static class Query    {        int l, r, idx;    }     // updating the bit array    static void update(int idx, int val,                        int bit[], int n)    {        for (; idx <= n; idx += idx & -idx)            bit[idx] += val;    }     // querying the bit array    static int query(int idx, int bit[], int n)    {        int sum = 0;        for (; idx > 0; idx -= idx & -idx)            sum += bit[idx];        return sum;    }     static void answeringQueries(int[] arr, int n,                                Query[] queries, int q)    {         // initialising bit array        int[] bit = new int[n + 1];        Arrays.fill(bit, 0);         // holds the rightmost index of any number        // as numbers of a[i] are less than or equal to 10^6        int[] last_visit = new int[MAX];        Arrays.fill(last_visit, -1);         // answer for each query        int[] ans = new int[q];        int query_counter = 0;        for (int i = 0; i < n; i++)        {             // If last visit is not -1 update -1 at the            // idx equal to last_visit[arr[i]]            if (last_visit[arr[i]] != -1)                update(last_visit[arr[i]] + 1, -1, bit, n);             // Setting last_visit[arr[i]] as i and updating            // the bit array accordingly            last_visit[arr[i]] = i;            update(i + 1, 1, bit, n);             // If i is equal to r of any query store answer            // for that query in ans[]            while (query_counter < q && queries[query_counter].r == i)            {                ans[queries[query_counter].idx] =                        query(queries[query_counter].r + 1, bit, n)                        - query(queries[query_counter].l, bit, n);                query_counter++;            }        }         // print answer for each query        for (int i = 0; i < q; i++)            System.out.println(ans[i]);    }     // Driver Code    public static void main(String[] args)    {        int a[] = { 1, 1, 2, 1, 3 };        int n = a.length;        Query[] queries = new Query[3];        for (int i = 0; i < 3; i++)            queries[i] = new Query();        queries[0].l = 0;        queries[0].r = 4;        queries[0].idx = 0;        queries[1].l = 1;        queries[1].r = 3;        queries[1].idx = 1;        queries[2].l = 2;        queries[2].r = 4;        queries[2].idx = 2;        int q = queries.length;        Arrays.sort(queries, new Comparator<Query>()        {            public int compare(Query x, Query y)            {                if (x.r < y.r)                    return -1;                else if (x.r == y.r)                    return 0;                else                    return 1;            }        });        answeringQueries(a, n, queries, q);    }} // This code is contributed by// sanjeev2552
# Python3 code to find number of# distinct numbers in a subarrayMAX = 1000001 # structure to store queriesclass Query:    def __init__(self, l, r, idx):        self.l = l        self.r = r        self.idx = idx # updating the bit arraydef update(idx, val, bit, n):    while idx <= n:        bit[idx] += val        idx += idx & -idx # querying the bit arraydef query(idx, bit, n):    summ = 0    while idx:        summ += bit[idx]        idx -= idx & -idx    return summ def answeringQueries(arr, n, queries, q):     # initialising bit array    bit = [0] * (n + 1)     # holds the rightmost index of    # any number as numbers of a[i]    # are less than or equal to 10^6    last_visit = [-1] * MAX     # answer for each query    ans = [0] * q     query_counter = 0    for i in range(n):         # If last visit is not -1 update -1 at the        # idx equal to last_visit[arr[i]]        if last_visit[arr[i]] != -1:            update(last_visit[arr[i]] + 1, -1, bit, n)         # Setting last_visit[arr[i]] as i and        # updating the bit array accordingly        last_visit[arr[i]] = i        update(i + 1, 1, bit, n)         # If i is equal to r of any query store answer        # for that query in ans[]        while query_counter < q and queries[query_counter].r == i:            ans[queries[query_counter].idx] = \                        query(queries[query_counter].r + 1, bit, n) - \                        query(queries[query_counter].l, bit, n)            query_counter += 1     # print answer for each query    for i in range(q):        print(ans[i]) # Driver Codeif __name__ == "__main__":    a = [1, 1, 2, 1, 3]    n = len(a)    queries = [Query(0, 4, 0),               Query(1, 3, 1),               Query(2, 4, 2)]    q = len(queries)     queries.sort(key = lambda x: x.r)    answeringQueries(a, n, queries, q) # This code is contributed by# sanjeev2552
<script> // JavaScript code to find number of// distinct numbers in a subarrayconst MAX = 1000001 // structure to store queriesclass Query{    constructor(l, r, idx){        this.l = l        this.r = r        this.idx = idx    }} // updating the bit arrayfunction update(idx, val, bit, n){    while(idx <= n){        bit[idx] += val        idx += idx & -idx    }} // querying the bit arrayfunction query(idx, bit, n){    let summ = 0    while(idx){        summ += bit[idx]        idx -= idx & -idx    }    return summ} function answeringQueries(arr, n, queries, q){     // initialising bit array    let bit = new Array(n+1).fill(0)     // holds the rightmost index of    // any number as numbers of a[i]    // are less than or equal to 10^6    let last_visit = new Array(MAX).fill(-1)     // answer for each query    let ans = new Array(q).fill(0);     let query_counter = 0    for(let i=0;i<n;i++){         // If last visit is not -1 update -1 at the        // idx equal to last_visit[arr[i]]        if(last_visit[arr[i]] != -1)            update(last_visit[arr[i]] + 1, -1, bit, n)         // Setting last_visit[arr[i]] as i and        // updating the bit array accordingly        last_visit[arr[i]] = i        update(i + 1, 1, bit, n)         // If i is equal to r of any query store answer        // for that query in ans[]        while(query_counter < q && queries[query_counter].r == i){            ans[queries[query_counter].idx] = query(queries[query_counter].r + 1, bit, n) - query(queries[query_counter].l, bit, n)            query_counter += 1        }    }     // print answer for each query    for(let i=0;i<q;i++)        document.write(ans[i],"</br>")} // Driver Code let a = [1, 1, 2, 1, 3]let n = a.lengthlet queries = [new Query(0, 4, 0),new Query(1, 3, 1),new Query(2, 4, 2)]let q = queries.length queries.sort((x,y) => x.r-y.r)answeringQueries(a, n, queries, q) // This code is contributed by shinjanpatra </script>
3
2
3
This article is contributed by Ayush Jha. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
sanjeev2552
shinjanpatra
array-range-queries
Binary Indexed Tree
Advanced Data Structure
Binary Indexed Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Agents in Artificial Intelligence
Decision Tree Introduction with example
AVL Tree | Set 2 (Deletion)
Disjoint Set Data Structures
Difference between B tree and B+ tree
Insert Operation in B-Tree
Design a Chess Game
Red-Black Tree | Set 2 (Insert)
Overview of Data Structures | Set 3 (Graph, Trie, Segment Tree and Suffix Tree)
Largest Rectangular Area in a Histogram | Set 1