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 }
Output: 3
Explanation:
Elements 19, 13 and 4 have even digit sum
in the subarray {3, 9, 13, 5, 4}.Input: arr[] = {0, 1, 2, 3, 4, 5, 6, 7}
query = { 3, 5 }
Output: 1
Explanation:
Only 4 has even digit sum
in the subarray {3, 4, 5}.
Naive approach:
 Find the answer for each query by simply traversing the array from index L till R and keep adding 1 to the count whenever the array element has even digit sum. Time Complexity of this approach will be O(n * q).
Efficient approach:
The idea is to build a Segment Tree.

Representation of Segment trees:
 Leaf Nodes are the elements of the input array.
 Each internal node contains the number of leaves which has even digit sum of all leaves under it.

Construction of Segment Tree from given array:
 We start with a segment arr[0 . . . n1]. and every time we divide the current segment into two halves(if it has not yet become a segment of length 1) and then call the same procedure on both halves and for each such segment, we store the number of elements which has even digit sum of all nodes under it.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; // 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; } // Procedure to build the segment tree void buildTree(vector< int >& tree, int * arr, int index, int s, int e) { // Reached the leaf node // of the segment tree if (s == e) { if (digitSum(arr[s]) & 1) tree[index] = 0; else tree[index] = 1; return ; } // Recursively call the buildTree // on both the nodes of the tree int mid = (s + e) / 2; buildTree(tree, arr, 2 * index, s, mid); buildTree(tree, arr, 2 * index + 1, mid + 1, e); tree[index] = tree[2 * index] + tree[2 * index + 1]; } // Query procedure to get the answer // for each query l and r are // query range int query(vector< int > tree, int index, int s, int e, int l, int r) { // Out of bound or no overlap if (r < s  l > e) return 0; // Complete overlap // Query range completely lies in // the segment tree node range if (s >= l && e <= r) { return tree[index]; } // Partially overlap // Query range partially lies in // the segment tree node range int mid = (s + e) / 2; return (query(tree, 2 * index, s, mid, l, r) + query(tree, 2 * index + 1, mid + 1, e, l, r)); } // Driver code int main() { int arr[] = { 7, 3, 19, 13, 5, 4 }; int n = sizeof (arr) / sizeof (arr[0]); vector< int > tree(4 * n + 1); int L = 1, R = 5; buildTree(tree, arr, 1, 0, n  1); cout << query(tree, 1, 0, n  1, L, R) << endl; return 0; } 
Python3
# Python3 implementation of the above approach # Function to find the digit sum # for a number def digitSum(num): sum = 0 ; while (num): sum + = (num % 10 ) num / / = 10 return sum # Procedure to build the segment tree def buildTree(tree, arr, index, s, e): # Reached the leaf node # of the segment tree if (s = = e): if (digitSum(arr[s]) & 1 ): tree[index] = 0 else : tree[index] = 1 return # Recursively call the buildTree # on both the nodes of the tree mid = (s + e) / / 2 buildTree(tree, arr, 2 * index, s, mid) buildTree(tree, arr, 2 * index + 1 , mid + 1 , e) tree[index] = (tree[ 2 * index] + tree[ 2 * index + 1 ]) # Query procedure to get the answer # for each query l and r are # query range def query(tree, index, s, e, l, r): # Out of bound or no overlap if (r < s or l > e): return 0 # Complete overlap # Query range completely lies in # the segment tree node range if (s > = l and e < = r): return tree[index] # Partially overlap # Query range partially lies in # the segment tree node range mid = (s + e) / / 2 return (query(tree, 2 * index, s, mid, l, r) + query(tree, 2 * index + 1 , mid + 1 , e, l, r)) # Driver code arr = [ 7 , 3 , 19 , 13 , 5 , 4 ] n = len (arr) tree = [ 0 ] * ( 4 * n + 1 ) L = 1 R = 5 buildTree(tree, arr, 1 , 0 , n  1 ); print (query(tree, 1 , 0 , n  1 , L, R)) # This code is contributed by Apurvaraj 
3
Time complexity: O(Q * log(N))
Recommended Posts:
 Queries for elements having values within the range A to B in the given index range using Segment Tree
 Queries for elements greater than K in the given index range using Segment Tree
 Queries for count of even digit sum elements in given range using MO's Algorithm
 Queries for greatest pair sum in the given index range using Segment Tree
 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
 Range Queries to count elements lying in a given Range : MO's Algorithm
 Number of elements greater than K in the range L to R using Fenwick Tree (Offline queries)
 Count of elements which are power of 2 in a given range subarray for Q queries
 Two equal sum segment range queries
 Count of elements having odd number of divisors in index range [L, R] for Q queries
 Queries for count of array elements with values in given range with updates
 Count of distinct numbers in an Array in a range for Online Queries using Merge Sort Tree
 Dynamic Segment Trees : Online Queries for Range Sum with Point Updates
 Segment Tree  Set 3 (XOR of given range)
 Segment Tree  (XOR of a given range )
 Segment Tree  Set 1 (Sum of given range)
 Queries to check whether a given digit is present in the given Range
 Binary Indexed Tree : Range Update and Range Queries
 Segment Tree  Set 2 (Range Minimum Query)
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.
Improved By : ApurvaRaj