Queries for number of distinct elements in a subarray | Set 2
Given an array arr[] of N integers and Q queries. Each query can be represented by two integers L and R. The task is to find the count of distinct integers in the subarray arr[L] to arr[R].
Examples:
Input: arr[] = {1, 1, 3, 3, 5, 5, 7, 7, 9, 9 }, L = 0, R = 4
Output: 3
Input: arr[] = { 1, 1, 2, 1, 3 }, L = 1, R = 3
Output : 2
Naive approach: In this approach, we will traverse through the range l, r and use a set to find all the distinct elements in the range and print them.
Time Complexity: O(q*n)
Efficient approach: Idea is to form a segment tree in which the nodes will store all the distinct elements in the range. For this purpose we can use a self-balancing BST or “set” data structure in C++.
Each query will return the size of the set.
Below is the implementation of the above approach:
// C++ implementation of above approach #include <bits/stdc++.h> using namespace std; // Each segment of the segment tree would be a set // to maintain distinct elements set< int >* segment; // Build the segment tree // i denotes current node, s denotes start and // e denotes the end of range for current node void build( int i, int s, int e, int arr[]) { // If start is equal to end then // insert the array element if (s == e) { segment[i].insert(arr[s]); return ; } // Else divide the range into two halves // (start to mid) and (mid+1 to end) // first half will be the left node // and the second half will be the right node build(2 * i, s, (s + e) / 2, arr); build(1 + 2 * i, 1 + (s + e) / 2, e, arr); // Insert the sets of right and left // node of the segment tree segment[i].insert(segment[2 * i].begin(), segment[2 * i].end()); segment[i].insert(segment[2 * i + 1].begin(), segment[2 * i + 1].end()); } // Query in an range a to b set< int > query( int node, int l, int r, int a, int b) { set< int > left, right, result; // If the range is out of the bounds // of this segment if (b < l || a > r) return result; // If the range lies in this segment if (a <= l && r <= b) return segment[node]; // Else query for the right and left // leaf node of this subtree // and insert them into the set left = query(2 * node, l, (l + r) / 2, a, b); result.insert(left.begin(), left.end()); right = query(1 + 2 * node, 1 + (l + r) / 2, r, a, b); result.insert(right.begin(), right.end()); // Return the result return result; } // Initialize the segment tree void init( int n) { // Get the height of the segment tree int h = ( int ) ceil (log2(n)); h = (2 * ( pow (2, h))) - 1; // Initialize the segment tree segment = new set< int >[h]; } // Function to get the result for the // subarray from arr[l] to arr[r] void getDistinct( int l, int r, int n) { // Query for the range set set< int > ans = query(1, 0, n - 1, l, r); cout << ans.size() << endl; } // Driver code int main() { int arr[] = { 1, 1, 2, 1, 3 }; int n = sizeof (arr) / sizeof (arr[0]); init(n); // Bulid the segment tree build(1, 0, n - 1, arr); // Query in range 0 to 4 getDistinct(0, 4, n); return 0; } |
3
Time Complexity: O(q*log(n))
Recommended Posts:
- Queries for number of distinct elements in a subarray
- Queries for number of distinct elements from a given index till last index in an array
- Distinct elements in subarray using Mo's Algorithm
- Longest subarray not having more than K distinct elements
- Queries for number of distinct integers in Suffix
- Number of elements less than or equal to a given number in a given subarray | Set 2 (Including Updates)
- Minimum number of subsets with distinct elements
- Queries to check whether all the elements in the given range occurs even number of times
- Number of elements less than or equal to a given number in a given subarray
- Number of elements greater than K in the range L to R using Fenwick Tree (Offline queries)
- Minimum number of segments required such that each segment has distinct elements
- Maximize the subarray sum after multiplying all elements of any subarray with X
- Queries for Composite numbers in subarray (With Point Updates)
- Range queries to count 1s in a subarray after flip operations
- Smallest subarray with k distinct numbers
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.