Skip to content
Related Articles
Query to count odd and even parity elements in subarray after XOR with K
• Difficulty Level : Medium
• Last Updated : 27 Nov, 2020

Given an array arr[] consisting of N elements and Q queries represented by L, R, and K. The task is to print the count of odd and even parity elements in the subarray [L, R] after Bitwise-XOR with K.

Examples:

Input: arr[] = {5, 2, 3, 1, 4, 8, 10}
query[] = {{0, 5, 3}, {1, 4, 8}, {4, 6, 10}}
Output:
4 2
1 3
2 1
Explanation:
In query 1, the odd and even parity elements in subarray [0:5] are [2, 1, 4, 8] and [5, 3]. Now after XOR with K = 3, the number of odd and even parity elements are 4 and 2 respectively.
In query 2, the odd and even parity elements in subarray [1:4] are [2, 1, 4] and . Now after XOR with K = 8, the number of odd and even parity elements are 1 and 3 respectively.
In query 3, the odd and even parity elements in subarray [4:6] are [4, 8] and . Now after XOR with K = 10, the number of odd and even parity elements are 2 and 1 respectively.

Approach: The idea is to use MO’s algorithm to pre-process all queries so that result of one query can be used in the next query.

• Sort all queries in a way that queries with L values from 0 to √n – 1 are put together, followed by queries from √n to 2 ×√n – 1, and so on. All queries within a block are sorted in increasing order of R values.
• Count the odd parity elements and then calculate the even parity elements as • Observation after XOR with odd and even parity elements:
• XOR of two odd parity elements is an even parity element.
• XOR of two even parity elements is an even parity element.
• XOR of one even parity element and another odd parity element is an odd parity element and vice-versa.
• Process all queries one by one and increase the count of odd parity elements and now we will check the parity of K. If K has an even parity then the count of odd and even parity remains the same else we swap them.
• Let count_oddP store the count of odd parity elements in previous query.
• Remove extra elements of previous query and add new elements for the current query. For example, if previous query was [0, 8] and the current query is [3, 9], then remove the elements arr, arr and arr and add arr.
• In order to display the results, sort the queries in the order they were provided.

Adding elements

• If the current element has odd parity then increase the count of odd parity.

Removing elements

• If the current element has odd parity then decrease the count of odd parity.

Below is the implementation of the above approach:

## C++

 `// C++ program to count odd and``// even parity elements in subarray``// after XOR with K` `#include ``using` `namespace` `std;` `#define MAX 100000` `// Variable to represent block size.``// This is made global so compare()``// of sort can use it``int` `block;` `// Structure to represent``// a query range``struct` `Query {``    ``// Starting index``    ``int` `L, R, K, index;` `    ``// Count of odd``    ``// parity elements``    ``int` `odd;` `    ``// Count of even``    ``// parity elements``    ``int` `even;``};` `// To store the count of``// odd parity elements``int` `count_oddP;` `// Function used to sort all queries so that``// all queries of the same block are arranged``// together and within a block, queries are``// sorted in increasing order of R values.``bool` `compare(Query x, Query y)``{``    ``// Different blocks, sort by block.``    ``if` `(x.L / block != y.L / block)``        ``return` `x.L / block < y.L / block;` `    ``// Same block, sort by R value``    ``return` `x.R < y.R;``}` `// Function used to sort all queries``// in order of their index value so``// that results of queries can be``// printed in same order as of input``bool` `compare1(Query x, Query y)``{``    ``return` `x.index < y.index;``}` `// Function to Add elements``// of current range``void` `add(``int` `currL, ``int` `a[])``{``    ``// _builtin_parity(x)returns true(1)``    ``// if the number has odd parity else``    ``// it returns false(0) for even parity.``    ``if` `(__builtin_parity(a[currL]))``        ``count_oddP++;``}` `// Function to remove elements``// of previous range``void` `remove``(``int` `currR, ``int` `a[])``{``    ``// _builtin_parity(x)returns true(1)``    ``// if the number has odd parity else``    ``// it returns false(0) for even parity.``    ``if` `(__builtin_parity(a[currR]))``        ``count_oddP--;``}` `// Function to generate the result of queries``void` `queryResults(``int` `a[], ``int` `n, Query q[],``                  ``int` `m)``{` `    ``// Initialize number of odd parity``    ``// elements to 0``    ``count_oddP = 0;` `    ``// Find block size``    ``block = (``int``)``sqrt``(n);` `    ``// Sort all queries so that queries of``    ``// same blocks are arranged together.``    ``sort(q, q + m, compare);` `    ``// Initialize current L, current R and``    ``// current result``    ``int` `currL = 0, currR = 0;` `    ``for` `(``int` `i = 0; i < m; i++) {` `        ``// L and R values of current range``        ``int` `L = q[i].L,``            ``R = q[i].R,``            ``k = q[i].K;` `        ``// Add Elements of current range``        ``while` `(currR <= R) {``            ``add(currR, a);``            ``currR++;``        ``}``        ``while` `(currL > L) {``            ``add(currL - 1, a);``            ``currL--;``        ``}` `        ``// Remove element of previous range``        ``while` `(currR > R + 1)` `        ``{``            ``remove``(currR - 1, a);``            ``currR--;``        ``}``        ``while` `(currL < L) {``            ``remove``(currL, a);``            ``currL++;``        ``}` `        ``// If parity of K is even``        ``// then the count of odd``        ``// and even parity remains``        ``// the same``        ``if` `(!__builtin_parity(k)) {``            ``q[i].odd = count_oddP;``            ``q[i].even``                ``= R - L + 1 - count_oddP;``        ``}``        ``// If parity of K is odd``        ``// we swap the count of``        ``// odd and even parity``        ``// elements``        ``else` `{``            ``q[i].odd``                ``= R - L + 1 - count_oddP;``            ``q[i].even = count_oddP;``        ``}``    ``}``}` `// Function to display the results of``// queries in their initial order``void` `printResults(Query q[], ``int` `m)``{``    ``sort(q, q + m, compare1);``    ``for` `(``int` `i = 0; i < m; i++) {``        ``cout << q[i].odd << ``" "``             ``<< q[i].even << endl;``    ``}``}` `// Driver Code``int` `main()``{` `    ``int` `arr[] = { 5, 2, 3, 1, 4, 8, 10 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);` `    ``Query q[] = { { 0, 5, 3, 0, 0, 0 },``                  ``{ 1, 4, 8, 1, 0, 0 },``                  ``{ 4, 6, 10, 2, 0, 0 } };` `    ``int` `m = ``sizeof``(q) / ``sizeof``(q);` `    ``queryResults(arr, n, q, m);` `    ``printResults(q, m);` `    ``return` `0;``}`

## Java

 `// Java program to count odd and``// even parity elements in subarray``// after XOR with K``import` `java.io.*;``import` `java.util.*;` `// Class to represent``// a query range``class` `Query``{``    ``int` `L, R, K, index;` `    ``// Count of odd``    ``// parity elements``    ``int` `odd;` `    ``// Count of even``    ``// parity elements``    ``int` `even;` `    ``Query(``int` `L, ``int` `R, ``int` `K,``          ``int` `index, ``int` `odd, ``int` `even)``    ``{``        ``this``.L = L;``        ``this``.R = R;``        ``this``.K = K;``        ``this``.index = index;``        ``this``.odd = odd;``        ``this``.even = even;``    ``}``}` `class` `GFG{` `// Variable to represent block size.``static` `int` `block;` `// To store the count of``// odd parity elements``static` `int` `count_oddP;` `// Function to Add elements``// of current range``static` `void` `add(``int` `currL, ``int` `a[])``{``    ` `    ``// _builtin_parity(x)returns true``    ``// if the number has odd parity else``    ``// it returns false for even parity.``    ``if` `(__builtin_parity(a[currL]))``        ``count_oddP++;``}` `// Function to remove elements``// of previous range``static` `void` `remove(``int` `currR, ``int` `a[])``{``    ` `    ``// _builtin_parity(x)returns true``    ``// if the number has odd parity else``    ``// it returns false for even parity.``    ``if` `(__builtin_parity(a[currR]))``        ``count_oddP--;``}` `// Function to generate the result of queries``static` `void` `queryResults(``int` `a[], ``int` `n, Query q[],``                         ``int` `m)``{``    ` `    ``// Initialize number of odd parity``    ``// elements to 0``    ``count_oddP = ``0``;` `    ``// Find block size``    ``block = (``int``)(Math.sqrt(n));` `    ``// sort all queries so that all queries``    ``// of the same block are arranged together``    ``// and within a block, queries are sorted``    ``// in increasing order of R values.``    ``Arrays.sort(q, (Query x, Query y) ->``    ``{``        ` `        ``// Different blocks, sort by block.``        ``if` `(x.L / block != y.L / block)``            ``return` `x.L / block - y.L / block;` `        ``// Same block, sort by R value``        ``return` `x.R - y.R;``    ``});` `    ``// Initialize current L, current R and``    ``// current result``    ``int` `currL = ``0``, currR = ``0``;` `    ``for``(``int` `i = ``0``; i < m; i++)``    ``{``        ` `        ``// L and R values of current range``        ``int` `L = q[i].L, R = q[i].R, k = q[i].K;` `        ``// Add Elements of current range``        ``while` `(currR <= R)``        ``{``            ``add(currR, a);``            ``currR++;``        ``}``        ``while` `(currL > L)``        ``{``            ``add(currL - ``1``, a);``            ``currL--;``        ``}` `        ``// Remove element of previous range``        ``while` `(currR > R + ``1``)``        ``{``            ``remove(currR - ``1``, a);``            ``currR--;``        ``}``        ``while` `(currL < L)``        ``{``            ``remove(currL, a);``            ``currL++;``        ``}` `        ``// If parity of K is even``        ``// then the count of odd``        ``// and even parity remains``        ``// the same``        ``if` `(!__builtin_parity(k))``        ``{``            ``q[i].odd = count_oddP;``            ``q[i].even = R - L + ``1` `- count_oddP;``        ``}``        ` `        ``// If parity of K is odd``        ``// we swap the count of``        ``// odd and even parity``        ``// elements``        ``else``        ``{``            ``q[i].odd = R - L + ``1` `- count_oddP;``            ``q[i].even = count_oddP;``        ``}``    ``}``}` `static` `boolean` `__builtin_parity(``int` `K)``{``    ``return` `(Integer.bitCount(K) % ``2``) == ``1``;``}` `// Function to display the results of``// queries in their initial order``static` `void` `printResults(Query q[], ``int` `m)``{``    ``Arrays.sort(q, (Query x, Query y) ->` `                ``// sort all queries``                ``// in order of their``                ``// index value so that results``                ``// of queries can be printed``                ``// in same order as of input);``                ``x.index - y.index);` `    ``for``(``int` `i = ``0``; i < m; i++)``    ``{``        ``System.out.println(q[i].odd + ``" "` `+``                           ``q[i].even);``    ``}``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ``int` `arr[] = { ``5``, ``2``, ``3``, ``1``, ``4``, ``8``, ``10` `};``    ``int` `n = arr.length;` `    ``Query q[] = ``new` `Query[``3``];``    ``q[``0``] = ``new` `Query(``0``, ``5``, ``3``, ``0``, ``0``, ``0``);``    ``q[``1``] = ``new` `Query(``1``, ``4``, ``8``, ``1``, ``0``, ``0``);``    ``q[``2``] = ``new` `Query(``4``, ``6``, ``10``, ``2``, ``0``, ``0``);` `    ``int` `m = q.length;` `    ``queryResults(arr, n, q, m);` `    ``printResults(q, m);``}``}` `// This code is contributed by jithin`
Output:
```4 2
1 3
2 1```

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer Geeks Classes Live

My Personal Notes arrow_drop_up