Given an array arr[] of size N, and an array Q[] consisting of M queries of type {L, R}, the task is to print the count of triplets whose XOR has an even number of set bits in the range [L, R], for each of the M queries.
Examples:
Input: arr[] = {1, 2, 3, 4, 5}, N = 5, Q[] = {{1, 4}, {3, 4}}, M = 2
Output: 3
0
Explanation:
Perform the query as following:
- Query(1, 4): Print 3. The triplets whose xor has an even number of set bits are {1, 2, 3}, {1, 3, 4} and {2, 3, 4}.
- Query(3, 4): Print 0. There are no triplets that satisfy the condition.
Input: arr[] = {3, 3, 3}, N = 2, Q[] = {{1, 3}}, M = 1
Output: 1
Approach: The given problem can be solved based on the following observations:
- The XOR of two numbers X and Y i.e X^Y can have an even number of set bits only if:
- Both X and Y have an even number of set bits.
- Both X and Y have an odd number of set bits.
- Thus, there are only cases, where the XOR of three numbers has an even number of set bits, which are:
- All three numbers have an even number of set bits.
- Exactly two of them have an odd number of set bits and the other has an even number of set bits.
- Therefore, the problem can be solved with the concept of prefix arrays by applying the above observations.
Follow the steps below to solve the problem:
- Initialize a prefix array say preo[] of size N+1, where preo[i] stores the number of elements up to index i, that have an odd number of set bits.
- Create another prefix array say pree of size N+1, where pree[i] stores the number of elements up to index i, that have an even number of set bits.
- Traverse the array arr[], and do the following:
- Use the __builtin_popcount() function to calculate the number of set bits in the current element.
- If the number of set bits is odd, increment preo[i]
- Otherwise, increment pree[i]
- Traverse the array Q[] and perform the following steps:
- Calculate the number of elements that have an odd number of set bits and store it in a variable say odd, using the preo[] array.
- Calculate the number of elements that have an even number of set bits and store it in a variable say even, using the pree [] array.
- Initialize a variable ans to 0 to store the count of triplets.
- If even is not less than 3, add evenC3 to ans.
- If even is not less than 1 and odd is not less than 2, add (oddC2)*(evenC1) to ans.
- Finally, print the count of triplets obtained in ans for the current query {L, R}.
Below is an implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int NCR( int N, int R)
{
if (R > N - R)
R = N - R;
int ans = 1;
for ( int i = 1; i <= R; i++) {
ans *= N - R + i;
ans /= i;
}
return ans;
}
void solveXorTriplets( int arr[], int N,
vector<pair< int , int > > Q, int M)
{
int preo[N + 1] = { 0 };
int pree[N + 1] = { 0 };
for ( int i = 0; i < N; i++) {
preo[i + 1] += preo[i];
pree[i + 1] += pree[i];
int setbits = __builtin_popcount(arr[i]);
if (setbits % 2)
preo[i + 1]++;
else
pree[i + 1]++;
}
for ( int i = 0; i < M; i++) {
int L = Q[i].first;
int R = Q[i].second;
int odd = preo[R] - preo[L - 1];
int even = pree[R] - pree[L - 1];
int ans = 0;
if (even >= 3)
ans += NCR(even, 3);
if (odd >= 2 && even >= 1)
ans += NCR(odd, 2) * NCR(even, 1);
cout << ans << endl;
}
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
int N = sizeof (arr) / sizeof (arr[0]);
vector<pair< int , int > > Q = { { 1, 4 }, { 3, 4 } };
int M = Q.size();
solveXorTriplets(arr, N, Q, M);
return 0;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
static class pair
{
int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
static int NCR( int N, int R)
{
if (R > N - R)
R = N - R;
int ans = 1 ;
for ( int i = 1 ; i <= R; i++)
{
ans *= N - R + i;
ans /= i;
}
return ans;
}
static void solveXorTriplets( int arr[], int N,
Vector<pair> Q, int M)
{
int preo[] = new int [N + 1 ];
int pree[] = new int [N + 1 ];
for ( int i = 0 ; i < N; i++)
{
preo[i + 1 ] += preo[i];
pree[i + 1 ] += pree[i];
int setbits = Integer.bitCount(arr[i]);
if (setbits % 2 != 0 )
preo[i + 1 ]++;
else
pree[i + 1 ]++;
}
for ( int i = 0 ; i < M; i++)
{
int L = Q.elementAt(i).first;
int R = Q.elementAt(i).second;
int odd = preo[R] - preo[L - 1 ];
int even = pree[R] - pree[L - 1 ];
int ans = 0 ;
if (even >= 3 )
ans += NCR(even, 3 );
if (odd >= 2 && even >= 1 )
ans += NCR(odd, 2 ) * NCR(even, 1 );
System.out.println(ans);
}
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , 4 , 5 };
int N = arr.length;
Vector<pair> Q = new Vector<>();
Q.add( new pair( 1 , 4 ));
Q.add( new pair( 3 , 4 ));
int M = Q.size();
solveXorTriplets(arr, N, Q, M);
}
}
|
Python3
def NCR(N, R):
if (R > N - R):
R = N - R
ans = 1
for i in range ( 1 ,R + 1 ):
ans * = N - R + i
ans / / = i
return ans
def solveXorTriplets(arr, N, Q, M):
preo = [ 0 ] * (N + 1 )
pree = [ 0 ] * (N + 1 )
for i in range (N):
preo[i + 1 ] + = preo[i]
pree[i + 1 ] + = pree[i]
setbits = bin (arr[i]).count( '1' )
if (setbits % 2 ):
preo[i + 1 ] + = 1
else :
pree[i + 1 ] + = 1
for i in range (M):
L = Q[i][ 0 ]
R = Q[i][ 1 ]
odd = preo[R] - preo[L - 1 ]
even = pree[R] - pree[L - 1 ]
ans = 0
if (even > = 3 ):
ans + = NCR(even, 3 )
if (odd > = 2 and even > = 1 ):
ans + = NCR(odd, 2 ) * NCR(even, 1 )
print (ans)
if __name__ = = '__main__' :
arr = [ 1 , 2 , 3 , 4 , 5 ]
N = len (arr)
Q = [ [ 1 , 4 ], [ 3 , 4 ] ]
M = len (Q)
solveXorTriplets(arr, N, Q, M)
|
C#
using System;
using System.Collections.Generic;
class pair{
int first, second;
pair( int first, int second)
{
this .first = first;
this .second = second;
}
public static int BitCount( int n)
{
var count = 0;
while (n != 0)
{
count++;
n &= (n - 1);
}
return count;
}
static int NCR( int N, int R)
{
if (R > N - R)
R = N - R;
int ans = 1;
for ( int i = 1; i <= R; i++)
{
ans *= N - R + i;
ans /= i;
}
return ans;
}
static void solveXorTriplets( int [] arr, int N,
List<pair> Q, int M)
{
int [] preo = new int [N + 1];
int [] pree = new int [N + 1];
for ( int i = 0; i < N; i++)
{
preo[i + 1] += preo[i];
pree[i + 1] += pree[i];
int setbits = BitCount(arr[i]);
if (setbits % 2 != 0)
preo[i + 1]++;
else
pree[i + 1]++;
}
for ( int i = 0; i < M; i++)
{
int L = Q[i].first;
int R = Q[i].second;
int odd = preo[R] - preo[L - 1];
int even = pree[R] - pree[L - 1];
int ans = 0;
if (even >= 3)
ans += NCR(even, 3);
if (odd >= 2 && even >= 1)
ans += NCR(odd, 2) * NCR(even, 1);
Console.WriteLine(ans);
}
}
public static void Main()
{
int [] arr = { 1, 2, 3, 4, 5 };
int N = arr.Length;
List<pair> Q = new List<pair>();
Q.Add( new pair(1, 4));
Q.Add( new pair(3, 4));
int M = Q.Count;
solveXorTriplets(arr, N, Q, M);
}
}
|
Javascript
<script>
function bitCount1(n) {
return n.toString(2).match(/1/g).length
}
function NCR(N, R)
{
if (R > N - R)
R = N - R;
var ans = 1;
for ( var i = 1; i <= R; i++) {
ans *= N - R + i;
ans /= i;
}
return ans;
}
function solveXorTriplets(arr, N, Q, M)
{
var preo = new Array(N+1).fill(0);
var pree = new Array(N+1).fill(0);
for ( var i = 0; i < N; i++) {
preo[i + 1] += preo[i];
pree[i + 1] += pree[i];
var setbits = bitCount1(arr[i]);
if (setbits % 2)
preo[i + 1]++;
else
pree[i + 1]++;
}
for ( var i = 0; i < M; i++) {
var L = Q[i][0];
var R = Q[i][1];
var odd = preo[R] - preo[L - 1];
var even = pree[R] - pree[L - 1];
var ans = 0;
if (even >= 3)
ans += NCR(even, 3);
if (odd >= 2 && even >= 1)
ans += NCR(odd, 2) * NCR(even, 1);
document.write(ans + "<br>" );
}
}
var arr = [1, 2, 3, 4, 5 ];
var N = arr.length;
var Q = [ [ 1, 4 ], [ 3, 4 ] ];
var M = Q.length;
solveXorTriplets(arr, N, Q, M);
</script>
|
Time Complexity: O(N+M)
Auxiliary Space: O(N)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
12 Jan, 2023
Like Article
Save Article