Skip to content
Related Articles

Related Articles

Queries for the count of even digit sum elements in the given range using Segment Tree.
  • Difficulty Level : Basic
  • Last Updated : 28 Aug, 2020

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:
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:
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
 



  1. 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. 
       
  2. Construction of Segment Tree from given array: 
    • We start with a segment arr[0 . . . n-1]. 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
class GFG{
 
// Function to find the digit sum
// for a number
static int digitSum(int num)
{
    int sum = 0;
    while (num > 0)
    {
        sum += (num % 10);
        num /= 10;
    }
    return sum;
}
 
// Procedure to build the segment tree
static void buildTree(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]) % 2 == 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
static int query(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
public static void main(String[] args)
{
    int arr[] = { 7, 3, 19, 13, 5, 4 };
    int n = arr.length;
    int []tree = new int[4 * n + 1];
 
    int L = 1, R = 5;
 
    buildTree(tree, arr, 1, 0, n - 1);
 
    System.out.print(query(tree, 1, 0,
                           n - 1, L, R) + "\n");
}
}
 
// This code is contributed by gauravrajput1

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
class GFG{
 
// Function to find the digit sum
// for a number
static int digitSum(int num)
{
    int sum = 0;
    while (num > 0)
    {
        sum += (num % 10);
        num /= 10;
    }
    return sum;
}
 
// Procedure to build the segment tree
static void buildTree(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]) % 2 == 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
static int query(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
public static void Main(String[] args)
{
    int []arr = { 7, 3, 19, 13, 5, 4 };
    int n = arr.Length;
    int []tree = new int[4 * n + 1];
 
    int L = 1, R = 5;
 
    buildTree(tree, arr, 1, 0, n - 1);
 
    Console.Write(query(tree, 1, 0,
                        n - 1, L, R) + "\n");
}
}
 
// This code is contributed by gauravrajput1

chevron_right


Output: 

3






 

Time complexity: O(Q * log(N))
 

competitive-programming-img

My Personal Notes arrow_drop_up
Recommended Articles
Page :