# Range Queries to count the number of even parity values with updates

Given an array arr[] of N integers, the task is to perform the following two queries:

• query(L, R): Print the number of Even Parity numbers in the subarray from L to R.
• update(i, x): Update the array element reference by index i to x.

Examples:

Input: arr[] = {18, 15, 8, 9, 14, 5}
Query 1: query(L = 0, R = 4)
Query 2: update(i = 3, x = 11)
Query 3: query(L = 0, R = 4)
Output:
3
2
Explanation:
Query 1: Subarray is {18, 15, 8, 9, 14}
Binary Representation of these elements –
18 => 10010, Parity = 2
15 => 1111, Parity = 4
8 => 1000, Parity = 1
9 => 1001, Parity = 2
14 => 1110, Parity = 3
Subarray[0-4] have 3 elements with even parity.
Query 2: Update arr = 11
Updated array, {18, 15, 8, 11, 14, 5}
Query 3: Subarray is {18, 15, 8, 11, 14}
Binary Representation of these elements –
18 => 10010, Parity = 2
15 => 1111, Parity = 4
8 => 1000, Parity = 1
11 => 1011, Parity = 3
14 => 1110, Parity = 3
Subarray[0-4] have 2 elements with even parity.

Approach: The idea is to use segment tree to query the count of the even parity elements in a array range and update simultaneously.

We can find the parity for the current value by iterating through each bit of the binary representation of the number and counting the number of set bits. Then check if the parity is even or not. If it has even parity the set it to 1 else to 0.

Building the segment tree:

• Leaf nodes of the segment tree is represented as either 0 (if it is odd parity number) or 1 (if it is even parity number).
• The internal nodes of the segment tree equal to the sum of its child nodes, thus a node represent the total Even Parity numbers in the range from L to R with range [L, R] falling under this node and the sub-tree underneath it.

Handling Queries:

• Query(L, R): Whenever we receive a query from start to end, we can query the segment tree for the sum of nodes in the range from start to end, which in turn represents the number of Even Parity numbers in the range start to end.
• Update(i, x): To perform a update query to update the value at index i to x, we check for the following cases:
• Case 1: If previous value and new value both are Even Parity numbers
Count of Even Parity numbers in the subarray does not change so we just update array and do not modify the segment tree
• Case 2: If previous value and new value both are not Even Parity numbers
Count of Even Parity numbers in the subarray does not change so we just update array and do not modify the segment tree
• Case 3: If previous value is a Even Parity number but new value is not a Even Parity number
Count of Even Parity numbers in the subarray decreases so we update array and add -1 to every range. The index i which is to be updated is a part of in the segment tree
• Case 4: If previous value is not a Even Parity number but new value is a Even Parity number
Count of Even Parity numbers in the subarray increases so we update array and add 1 to every range. The index i which is to be updated is a part of in the segment tree

Below is the implementation of the above approach:

## C++

 `// C++ implementation to find ` `// number of Even Parity numbers ` `// in a subarray and performing updates ` ` `  `#include ` `using` `namespace` `std; ` ` `  `#define MAX 1000 ` ` `  `// Function that returns true if count ` `// of set bits in x is even ` `bool` `isEvenParity(``int` `x) ` `{ ` `    ``// parity will store the ` `    ``// count of set bits ` `    ``int` `parity = 0; ` `    ``while` `(x != 0) { ` `        ``if` `(x & 1) ` `            ``parity++; ` `        ``x = x >> 1; ` `    ``} ` ` `  `    ``if` `(parity % 2 == 0) ` `        ``return` `true``; ` `    ``else` `        ``return` `false``; ` `} ` ` `  `// A utility function to get ` `// the middle index ` `int` `getMid(``int` `s, ``int` `e) ` `{ ` `    ``return` `s + (e - s) / 2; ` `} ` ` `  `// Recursive function to get the number ` `// of Even Parity numbers in a given range ` `int` `queryEvenParityUtil( ` `    ``int``* segmentTree, ``int` `segmentStart, ` `    ``int` `segmentEnd, ``int` `queryStart, ` `    ``int` `queryEnd, ``int` `index) ` `{ ` `    ``// If segment of this node is a part ` `    ``// of given range, then return ` `    ``// the number of Even Parity numbers ` `    ``// in the segment ` `    ``if` `(queryStart <= segmentStart ` `        ``&& queryEnd >= segmentEnd) ` `        ``return` `segmentTree[index]; ` ` `  `    ``// If segment of this node ` `    ``// is outside the given range ` `    ``if` `(segmentEnd < queryStart ` `        ``|| segmentStart > queryEnd) ` `        ``return` `0; ` ` `  `    ``// If a part of this segment ` `    ``// overlaps with the given range ` `    ``int` `mid = getMid(segmentStart, segmentEnd); ` `    ``return` `queryEvenParityUtil( ` `               ``segmentTree, segmentStart, mid, ` `               ``queryStart, queryEnd, 2 * index + 1) ` `           ``+ queryEvenParityUtil( ` `                 ``segmentTree, mid + 1, segmentEnd, ` `                 ``queryStart, queryEnd, 2 * index + 2); ` `} ` ` `  `// Recursive function to update ` `// the nodes which have the given ` `// index in their range ` `void` `updateValueUtil( ` `    ``int``* segmentTree, ``int` `segmentStart, ` `    ``int` `segmentEnd, ``int` `i, ``int` `diff, ``int` `si) ` `{ ` `    ``// Base Case: ` `    ``if` `(i < segmentStart || i > segmentEnd) ` `        ``return``; ` ` `  `    ``// If the input index is in range ` `    ``// of this node, then update the value ` `    ``// of the node and its children ` `    ``segmentTree[si] = segmentTree[si] + diff; ` `    ``if` `(segmentEnd != segmentStart) { ` ` `  `        ``int` `mid = getMid( ` `            ``segmentStart, segmentEnd); ` `        ``updateValueUtil( ` `            ``segmentTree, segmentStart, ` `            ``mid, i, diff, 2 * si + 1); ` `        ``updateValueUtil( ` `            ``segmentTree, mid + 1, segmentEnd, ` `            ``i, diff, 2 * si + 2); ` `    ``} ` `} ` ` `  `// Function to update a value in the ` `// input array and segment tree ` `void` `updateValue(``int` `arr[], ``int``* segmentTree, ` `                 ``int` `n, ``int` `i, ``int` `new_val) ` `{ ` `    ``// Check for erroneous input index ` `    ``if` `(i < 0 || i > n - 1) { ` `        ``printf``(``"Invalid Input"``); ` `        ``return``; ` `    ``} ` ` `  `    ``int` `diff, oldValue; ` ` `  `    ``oldValue = arr[i]; ` ` `  `    ``// Update the value in array ` `    ``arr[i] = new_val; ` ` `  `    ``// Case 1: Old and new values ` `    ``// both are Even Parity numbers ` `    ``if` `(isEvenParity(oldValue) ` `        ``&& isEvenParity(new_val)) ` `        ``return``; ` ` `  `    ``// Case 2: Old and new values ` `    ``// both not Even Parity numbers ` `    ``if` `(!isEvenParity(oldValue) ` `        ``&& !isEvenParity(new_val)) ` `        ``return``; ` ` `  `    ``// Case 3: Old value was Even Parity, ` `    ``// new value is non Even Parity ` `    ``if` `(isEvenParity(oldValue) ` `        ``&& !isEvenParity(new_val)) { ` `        ``diff = -1; ` `    ``} ` ` `  `    ``// Case 4: Old value was non Even Parity, ` `    ``// new_val is Even Parity ` `    ``if` `(!isEvenParity(oldValue) ` `        ``&& !isEvenParity(new_val)) { ` `        ``diff = 1; ` `    ``} ` ` `  `    ``// Update the values of ` `    ``// nodes in segment tree ` `    ``updateValueUtil(segmentTree, 0, ` `                    ``n - 1, i, diff, 0); ` `} ` ` `  `// Return number of Even Parity numbers ` `void` `queryEvenParity(``int``* segmentTree, ` `                     ``int` `n, ``int` `queryStart, ` `                     ``int` `queryEnd) ` `{ ` `    ``int` `EvenParityInRange ` `        ``= queryEvenParityUtil( ` `            ``segmentTree, 0, n - 1, ` `            ``queryStart, queryEnd, 0); ` ` `  `    ``cout << EvenParityInRange << ``"\n"``; ` `} ` ` `  `// Recursive function that constructs ` `// Segment Tree for the given array ` `int` `constructSTUtil(``int` `arr[], ` `                    ``int` `segmentStart, ` `                    ``int` `segmentEnd, ` `                    ``int``* segmentTree, ` `                    ``int` `si) ` `{ ` `    ``// If there is one element in array, ` `    ``// check if it is Even Parity number ` `    ``// then store 1 in the segment tree ` `    ``// else store 0 and return ` `    ``if` `(segmentStart == segmentEnd) { ` ` `  `        ``// if arr[segmentStart] is ` `        ``// Even Parity number ` `        ``if` `(isEvenParity(arr[segmentStart])) ` `            ``segmentTree[si] = 1; ` `        ``else` `            ``segmentTree[si] = 0; ` ` `  `        ``return` `segmentTree[si]; ` `    ``} ` ` `  `    ``// If there are more than one elements, ` `    ``// then recur for left and right subtrees ` `    ``// and store the sum of the ` `    ``// two values in this node ` `    ``int` `mid = getMid(segmentStart, ` `                     ``segmentEnd); ` `    ``segmentTree[si] ` `        ``= constructSTUtil( ` `              ``arr, segmentStart, mid, ` `              ``segmentTree, si * 2 + 1) ` `          ``+ constructSTUtil( ` `                ``arr, mid + 1, segmentEnd, ` `                ``segmentTree, si * 2 + 2); ` `    ``return` `segmentTree[si]; ` `} ` ` `  `// Function to construct a segment ` `// tree from given array ` `int``* constructST(``int` `arr[], ``int` `n) ` `{ ` `    ``// Height of segment tree ` `    ``int` `x = (``int``)(``ceil``(log2(n))); ` ` `  `    ``// Maximum size of segment tree ` `    ``int` `max_size = 2 * (``int``)``pow``(2, x) - 1; ` ` `  `    ``int``* segmentTree = ``new` `int``[max_size]; ` ` `  `    ``// Fill the allocated memory st ` `    ``constructSTUtil(arr, 0, n - 1, ` `                    ``segmentTree, 0); ` ` `  `    ``// Return the constructed segment tree ` `    ``return` `segmentTree; ` `} ` ` `  `// Driver Code ` `int` `main() ` `{ ` ` `  `    ``int` `arr[] = { 18, 15, 8, 9, 14, 5 }; ` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr); ` ` `  `    ``// Build segment tree from given array ` `    ``int``* segmentTree = constructST(arr, n); ` ` `  `    ``// Query 1: Query(start = 0, end = 4) ` `    ``int` `start = 0; ` `    ``int` `end = 4; ` `    ``queryEvenParity(segmentTree, n, start, end); ` ` `  `    ``// Query 2: Update(i = 3, x = 11), ` `    ``// i.e Update a[i] to x ` `    ``int` `i = 3; ` `    ``int` `x = 11; ` `    ``updateValue(arr, segmentTree, n, i, x); ` ` `  `    ``// Query 3: Query(start = 0, end = 4) ` `    ``start = 0; ` `    ``end = 4; ` `    ``queryEvenParity( ` `        ``segmentTree, n, start, end); ` ` `  `    ``return` `0; ` `} `

Output:

```3
2
``` My Personal Notes arrow_drop_up Check out this Author's contributed articles.

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.