
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Count Even Digit Sum Elements in Given Range Using Segment Tree
Introduction
In this tutorial, we implement an approach in C++ to resolve queries for the count of even digit sum elements in the given range. We use a segment tree. To solve this task, we consider an array of elements with queries defining the range of the subarray. In that subarray count the even digit sum elements. Predefine the element array and the queries to resolve the problem using the Segment tree.
What is a segment tree?
A segment tree is a binary data structure that stores array interval or segment information. It efficiently solves range or segment query problems. Each node of the Segment tree represents a range of the array and the leaves represent array elements.
The key operations of the segment tree are Update and Range.
In this tutorial, we use the Segment Tree concept to resolve the queries of the element array.
Demonstration 1
Array = {1, 3, 4, 5, 6, 7, 8, 9} Queries = [2, 5]
Output
2
Explanation
In the above input array, the starting index is 0. The queries define the input array indices. By considering the queries the revised sub-array is {4, 5, 6, 7}. In this subarray, there are 2 even sum digits, 4 and 6.
Demonstration 2
Array = {2, 8, 1, 5, 6, 7} Queries = [1,3]
Output
1
Explanation
In the above input array, there are 6 elements, and the starting index number is 0. The query starts at indexes 1 to 3. The revised subarray using Queries is {8, 1, 5}. In this subarray, there is one even sum digit number 8.
C++ Library Functions
Syntax
vector : vector is a dynamic array in C++ that does not restrict array size. Inserting and deleting array elements is done efficiently with it. It is defined in the vector header file of the C++ library.
vector<data_type> vector_name;
sizeof(): it is a unary operator in C++. it helps in calculating the size of variables, constants, and data types during compile time.
sizeof(variable_name);
size(): It is a standard library function of C++. it returns the size of the input string.
string_name.size();
Algorithm
Consider an input array arr[] and define its elements.
Use this array to build a segment tree.
Each array element represents the leaves of the segment tree.
To build a segment tree, start with two array elements and divide the tree into two parts. Now take the third array element and insert it as per the Segment tree insertion rules. Similarly, insert all array elements.
Count the even sum digit elements by traversing the tree.
Initialize a counter variable and increase its count when an even sum digit element is found.
Print the counter variable result.
Example 1
Here, we implement the task with C++. Define a "constructSegmentTree" function to build a segment tree using the arr[] elements. Initialize the queries using the rangeBegin and RangeFinish variables and the function "querySegTree" computes the results according to the queries.
#include <iostream> #include <vector> using namespace std; // Constructing the Segment tree node using structure struct Node{ int cnt; // counter variable to count even digit sum elments }; // Function to initialize the segment tree void constructSegmentTree(const vector<int>& arr, vector<Node>& segtree, int node, int begin, int finish) { if (begin == finish) { // Leaf node segtree[node].cnt = (arr[begin] % 2 == 0) ? 1 : 0; } else { int between = (begin + finish) / 2; int lChild = 2 * node + 1; int rChild = 2 * node + 2; // Building substrees constructSegmentTree(arr, segtree, lChild, begin, between); constructSegmentTree(arr, segtree, rChild, between + 1, finish); // Combine results of left and right subtrees segtree[node].cnt = segtree[lChild].cnt + segtree[rChild].cnt; } } // query resolution function int querySegTree(const vector<Node>& segtree, int node, int begin, int finish, int rangeBegin, int rangeFinish) { if (begin > rangeFinish || finish < rangeBegin) return 0; if (rangeBegin <= begin && rangeFinish >= finish) return segtree[node].cnt; int between = (begin + finish) / 2; int lChild = 2 * node + 1; int rChild = 2 * node + 2; int lResult = querySegTree(segtree, lChild, begin, between, rangeBegin, rangeFinish); int rResult = querySegTree(segtree, rChild, between + 1, finish, rangeBegin, rangeFinish); return lResult + rResult; } // code controller int main(){ // vector array vector<int> arr = {2, 5, 3, 7, 6, 8, 1}; int s = arr.size(); vector<Node> segtree(4 * s); //defining the segment tree constructSegmentTree(arr, segtree, 0, 0, s - 1); //queries int rangeBegin = 1; int rangeFinish = 4; int counter = querySegTree(segtree, 0, 0, s - 1, rangeBegin, rangeFinish); cout << "Count of elements with even digit sum in the range [" << rangeBegin << ", " << rangeFinish << "]: "<< counter << endl; return 0; }
Output
Count of elements with even digit sum in the range [1, 4] : 1
Example 2
Here, we implement the task using C++. Initialize an array with all its elements. The predefined queries represent the indices of the array. Construct the Segment tree using the array element and user-defined function and count the number of even sum digits.
#include <bits/stdc++.h> using namespace std; int evenSumDigit(int n){ int addition = 0; while (n){ addition += (n % 10); n /= 10; } return addition; } // building the Segment Tree void constructSegmentTree(vector<int>& segtree, int* a, int indexNo, int t, int f){ //tree leaf node if (t == f){ if (evenSumDigit(a[t]) & 1) segtree[indexNo] = 0; else segtree[indexNo] = 1; return; } int between = (t + f) / 2; constructSegmentTree(segtree, a, 2 * indexNo, t, between); constructSegmentTree(segtree, a, 2 * indexNo + 1,between + 1, f); segtree[indexNo] = segtree[2 * indexNo] + segtree[2 * indexNo + 1]; } // processing queries int queryArr(vector<int> segtree, int indexNo,int t, int f, int m, int q){ if (q < t || m > f) return 0; if (t >= m && f <= q){ return segtree[indexNo]; } int between = (t + f) / 2; return (queryArr(segtree, 2 * indexNo, t, between, m, q) + queryArr(segtree, 2 * indexNo + 1, between + 1, f, m, q)); } // code controller int main(){ int a[] = { 7, 3, 19, 13, 5, 4 }; int s = sizeof(a) / sizeof(a[0]); vector<int> segtree(4 * s + 1); int M = 2, S = 6; constructSegmentTree(segtree, a, 1, 0, s - 1); cout << "Number of even digit sum elements are: "<< queryArr(segtree, 1, 0, s - 1, M, S) << endl; return 0; }
Output
Number of even digit sum elements are: 3
Conclusion
We have reached the end of this tutorial. Here, we find an approach to solving queries for the count of even digit sum elements in the given range through a Segment Tree. We implemented two ways to resolve the problem statement using the Segment tree. The demonstrations used in this tutorial elaborate on the problem statement's purpose.