Find the count of distinct numbers in a range
source link: https://www.geeksforgeeks.org/find-the-count-of-distinct-numbers-in-a-range/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
- Last Updated : 09 Apr, 2020
Given an array of size N containing numbers only from 0 to 63, and you are asked Q queries regarding it.
Queries are as follows:
- 1 X Y i.e Change the element at index X to Y
- 2 L R i.e Print the count of distinct elements present in between L and R inclusive
Examples:
Input: N = 7 ar = {1, 2, 1, 3, 1, 2, 1} Q = 5 { {2, 1, 4}, {1, 4, 2}, {1, 5, 2}, {2, 4, 6}, {2, 1, 7} } Output: 3 1 2 Input: N = 15 ar = {4, 6, 3, 2, 2, 3, 6, 5, 5, 5, 4, 2, 1, 5, 1} Q = 5 { {1, 6, 5}, {1, 4, 2}, {2, 6, 14}, {2, 6, 8}, {2, 1, 6} }; Output: 5 2 5
Pre-requisites: Segment Tree and Bit Manipulation
Approach:
- The bitMask formed in the question will denote the presence of ith number or not, we will find out that by checking the ith bit of our bitMask, if the ith bit is on, that means i’th element is present, otherwise not present.
- Build a classical segment tree and each of its nodes will contain a bitmask which is used to decode the number of distinct elements in that particular segment which is defined by the particular node.
- Build the segment Tree in a bottom-up manner, therefore the bitMask for the current node of the segment tree can be easily calculated by performing bitwise OR operation on the bitMasks of this node’s right and left child. Leaf nodes will be handled separately. Updation will also be done in the same manner.
Below is the implementation of the above approach:
- Python3
// C++ Program to find the distinct
// elements in a range
#include <bits/stdc++.h>
using
namespace
std;
// Function to perform queries in a range
long
long
query(
int
start,
int
end,
int
left,
int
right,
int
node,
long
long
seg[])
{
// No overlap
if
(end < left || start > right) {
return
0;
}
// Totally Overlap
else
if
(start >= left && end <= right) {
return
seg[node];
}
// Parital Overlap
else
{
int
mid = (start + end) / 2;
// Finding the Answer
// for the left Child
long
long
leftChild = query(start, mid, left,
right, 2 * node, seg);
// Finding the Answer
// for the right Child
long
long
rightChild = query(mid + 1, end, left,
right, 2 * node + 1, seg);
// Combining the BitMasks
return
(leftChild | rightChild);
}
}
// Function to perform update operation
// in the Segment seg
void
update(
int
left,
int
right,
int
index,
int
Value,
int
node,
int
ar[],
long
long
seg[])
{
if
(left == right) {
ar[index] = Value;
// Forming the BitMask
seg[node] = (1LL << Value);
return
;
}
int
mid = (left + right) / 2;
if
(index > mid) {
// Updating the left Child
update(mid + 1, right, index, Value, 2 * node + 1, ar, seg);
}
else
{
// Updating the right Child
update(left, mid, index, Value, 2 * node, ar, seg);
}
// Updating the BitMask
seg[node] = (seg[2 * node] | seg[2 * node + 1]);
}
// Building the Segment Tree
void
build(
int
left,
int
right,
int
node,
int
ar[],
long
long
seg[])
{
if
(left == right) {
// Building the Initial BitMask
seg[node] = (1LL << ar[left]);
return
;
}
int
mid = (left + right) / 2;
// Building the left seg tree
build(left, mid, 2 * node, ar, seg);
// Building the right seg tree
build(mid + 1, right, 2 * node + 1, ar, seg);
// Forming the BitMask
seg[node] = (seg[2 * node] | seg[2 * node + 1]);
}
// Utility Function to answer the queries
void
getDistinctCount(vector<vector<
int
> >& queries,
int
ar[],
long
long
seg[],
int
n)
{
for
(
int
i = 0; i < queries.size(); i++) {
int
op = queries[i][0];
if
(op == 2) {
int
l = queries[i][1], r = queries[i][2];
long
long
tempMask = query(0, n - 1, l - 1,
r - 1, 1, seg);
int
countOfBits = 0;
// Counting the set bits which denote the
// distinct elements
for
(
int
i = 63; i >= 0; i--) {
if
(tempMask & (1LL << i)) {
countOfBits++;
}
}
cout << countOfBits <<
'\n'
;
}
else
{
int
index = queries[i][1];
int
val = queries[i][2];
// Updating the value
update(0, n - 1, index - 1, val, 1, ar, seg);
}
}
}
// Driver Code
int
main()
{
int
n = 7;
int
ar[] = { 1, 2, 1, 3, 1, 2, 1 };
long
long
seg[4 * n] = { 0 };
build(0, n - 1, 1, ar, seg);
int
q = 5;
vector<vector<
int
> > queries = {
{ 2, 1, 4 },
{ 1, 4, 2 },
{ 1, 5, 2 },
{ 2, 4, 6 },
{ 2, 1, 7 }
};
getDistinctCount(queries, ar, seg, n);
return
0;
}
3 1 2
Time complexity: O(N + Q*Log(N))
Attention reader! Don’t stop learning now. Get hold of all the important Comcompetitivepetitve Programming concepts with the Competitive Programming Live course.
Recommend
-
5
Oracle 12.1.0.2新特性 Approximate Count Distinct
-
4
Find duplicate numbers in a table, then count the number of duplicates advertisements How would I take an array with long list of numbers that...
-
5
Big Data Counting: How to count a billion distinct objects using only 1.5KB of Memory...
-
2
SQL Authority with Pinal DaveMS Access – Count Distinct ValuesI love answering random questions and particularly when they are from my paying clients of
-
2
Improve Article Count all N-length arrays made up of distinct consecutive elements whose first and last elements are equalLast Updated : 27 Apr, 2021Given two integers M...
-
6
Aug 17 2021
-
5
Approximate Count-Distinct using Flajolet Martin Algorithm 6 min read 2949 reads Pu...
-
6
Count Distinct Subsequences "Distinct Subsequences"Given a string S and a string T, count the number of distinct subsequences of T in S.Here is an example: S = "rabbbit", T = "rabbit"Re...
-
6
Count distinct elements in every windowCount distinct elements in every window | SDE Sheet | HashingHi. In this video, we will
-
2
Count of Distinct Integers Count of Distinct Integers Given a board with an integer...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK