# Queries for count of even digit sum elements in given range using MO’s Algorithm

Given an array **arr[]** of **N** elements, the task is to answer Q queries each having two integers **L** and **R**. For each query, the task is to find the number of elements in the subarray** arr[L…R]** whose digit sum is even.

**Examples:**

Input:arr[] = {7, 3, 19, 13, 5, 4}

query = { {1, 5}, {0, 1} }

Output:3

Explanation:

Query 1: Elements 19, 13 and 4 have even digit sum in the subarray: {3, 9, 13, 5, 4}.

Query 2: No elements have even sum in the subarray: {7, 3}

Input:arr[] = {0, 1, 2, 3, 4, 5, 6, 7}

query = { 3, 5 }

Output:1

We have already discussed this approach: Queries for the count of even digit sum elements in the given range using Segment Tree

**Approach: (Using MO’s Algorithm)**

The idea is 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. - Process all queries one by one and increase the count of even digit sum elements and store the result in the structure.
- Let
**count_even**store the count of even digits sum elements in the 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.

Helper functions:

Adding elements()If the current element has even digit sum then increase the count of count_even.

Removing elements()If the current element has even digit sum then decrease the count of count_even.

Below code is the implementation of the above approach:

## C++

`// C++ program to count of even ` `// digit sum elements in the given ` `// range using MO's algorithm ` ` ` `#include <bits/stdc++.h> ` `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; ` ` ` ` ` `// Ending index ` ` ` `int` `R; ` ` ` ` ` `// Index of query ` ` ` `int` `index; ` ` ` ` ` `// Count of even ` ` ` `// even digit sum ` ` ` `int` `even; ` `}; ` ` ` `// To store the count of ` `// even digit sum ` `int` `count_even; ` ` ` `// 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 find the digit sum ` `// for a number ` `int` `digitSum(` `int` `num) ` `{ ` ` ` `int` `sum = 0; ` ` ` `while` `(num) { ` ` ` `sum += (num % 10); ` ` ` `num /= 10; ` ` ` `} ` ` ` ` ` `return` `sum; ` `} ` ` ` `// Function to Add elements ` `// of current range ` `void` `add(` `int` `currL, ` `int` `a[]) ` `{ ` ` ` `// If digit sum of a[currL] ` ` ` `// is even then increment ` ` ` `if` `(digitSum(a[currL]) % 2 == 0) ` ` ` `count_even++; ` `} ` ` ` `// Function to remove elements ` `// of previous range ` `void` `remove` `(` `int` `currR, ` `int` `a[]) ` `{ ` ` ` ` ` `// If digit sum of a[currL] ` ` ` `// is even then decrement ` ` ` `if` `(digitSum(a[currR]) % 2 == 0) ` ` ` `count_even--; ` `} ` ` ` `// Function to generate ` `// the result of queries ` `void` `queryResults(` `int` `a[], ` `int` `n, ` ` ` `Query q[], ` `int` `m) ` `{ ` ` ` ` ` `// Initialize number of ` ` ` `// even digit sum to 0 ` ` ` `count_even = 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; ` ` ` ` ` `// 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++; ` ` ` `} ` ` ` ` ` `q[i].even = count_even; ` ` ` `} ` `} ` `// 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].even << endl; ` ` ` `} ` `} ` ` ` `// Driver Code ` `int` `main() ` `{ ` ` ` ` ` `int` `arr[] = { 5, 2, 3, 1, 4, 8, 10, 12 }; ` ` ` `int` `n = ` `sizeof` `(arr) / ` `sizeof` `(arr[0]); ` ` ` ` ` `Query q[] = { { 1, 3, 0, 0 }, ` ` ` `{ 0, 4, 1, 0 }, ` ` ` `{ 4, 7, 2, 0 } }; ` ` ` ` ` `int` `m = ` `sizeof` `(q) / ` `sizeof` `(q[0]); ` ` ` ` ` `queryResults(arr, n, q, m); ` ` ` ` ` `printResults(q, m); ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

1 2 2

**Time Complexity:** O(Q x √N)

## Recommended Posts:

- Range Queries to count elements lying in a given Range : MO's Algorithm
- Queries for the count of even digit sum elements in the given range using Segment Tree.
- Queries for elements having values within the range A to B using MO's Algorithm
- Queries to count integers in a range [L, R] such that their digit sum is prime and divisible by K
- Count numbers divisible by K in a range with Fibonacci digit sum for Q queries
- Queries for Count of divisors of product of an Array in given range | Set 2 (MO's Algorithm)
- Range Queries for count of Armstrong numbers in subarray using MO's algorithm
- Count of elements which are power of 2 in a given range subarray for Q queries
- Queries for count of array elements with values in given range with updates
- Count of elements having odd number of divisors in index range [L, R] for Q queries
- Queries to check whether a given digit is present in the given Range
- Range Queries to find the Element having Maximum Digit Sum
- Count of Numbers in Range where first digit is equal to last digit of the number
- Queries for elements having values within the range A to B in the given index range using Segment Tree
- Count numbers in a range with digit sum divisible by K having first and last digit different
- Find the XOR of the elements in the given range [L, R] with the value K for a given set of queries
- Range Queries for Frequencies of array elements
- Queries for number of array elements in a range with Kth Bit Set
- Queries for GCD of all numbers of an array except elements in a given range
- Array range queries for elements with frequency same as value

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.