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 [3]. 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 [10]. 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[0], arr[1] and arr[2] and add arr[9].
• In order to display the results, sort the queries in the order they were provided.

• 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[0]);` `    ``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[0]);` `    ``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.  Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price.

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

My Personal Notes arrow_drop_up