# Merge Sort Tree in C++

We are given an integer array, a set of segment start and end pointers and a key value and the problem statement here is to find all the values in the given range which are smaller than or equal to the given key value.

## Let us understand with example

Input − arr[] = {7, 8 , 1, 4 , 6 , 8 , 10 }

Segment 1: start = 2, end = 4, k = 2

Segment 2: start = 1, end = 6, k = 3

Output − Count of number which are smaller than or equal to key value in the given range are 2 6

Explanation − [8, 1, 4] represents the range from 2 to 4 and 2 is the 2nd smallest number in the range [7, 8 , 1, 4 , 6 , 8 ] represents the range from 1 to 6 and 6 is the 3rd smallest number in the range

Input − arr[] = {2, 7 , 9, 4 , 6 , 5 , 1 |

Segment 1: start = 3, end = 6, k = 4

Segment 2: start = 2, end = 5, k = 3

Output − Count of number which are smaller than or equal to key value in the given range are: 9 7

Explanation − [9, 4 , 6 , 5] represents the range from 3 to 6 and 9 is the 4th smallest number in the given range [7 , 9, 4 , 6 ] represents the range from 2 to 4 and 7 is the 3rd smallest number in the given segment range

## Approach used in the below program is as follows −

• Declare an integer type array. Calculate the size of an array. Declare a vector type variable forming the pair of integer types. Start FOR loop to push the data from array to vector.

• Sort the given vector. Create a vector array of integer types with the MAX size.

• Call the function as generateTree(1, 0, size - 1, vec, tree) and set getSmallestIndex to queryWrapper(2, 5, 2, size, vec, tree).

• Print the input[getSmallestIndex].

• Set getSmallestIndex to call the function as queryWrapper(1, 6, 4, size, vec, tree).

• Inside the function as void generateTree(int treeIndex, int leftIndex, int rightIndex, vector<pair<int, int> > &a, vector<int> tree[])

• Check IF leftIndex to rightIndex then set tree[treeIndex].push_back(a[leftIndex].second) and return

• Set midValue to (leftIndex + rightIndex) / 2and call generateTree(2 * treeIndex, leftIndex, midValue, a, tree), generateTree(2 * treeIndex + 1, midValue + 1, rightIndex, a, tree) and merge(tree[2 * treeIndex].begin(), tree[2 * treeIndex].end(), tree[2 * treeIndex + 1].begin(). Set tree[2 * treeIndex + 1].end(),back_inserter(tree[treeIndex]))

• Inside the function as int calculateKSmallest(int startIndex, int endIndex, int queryStart, int queryEnd, int treeIndex, int key, vector tree[])

• Check IF startIndex to endIndex then return tree[treeIndex][0]

• Set mid to (startIndex + endIndex) / 2, last_in_query_range to (upper_bound(tree[2 * treeIndex].begin(),tree[2 * treeIndex].end(), queryEnd) - tree[2 * treeIndex].begin())

• set first_in_query_range to (lower_bound(tree[2 * treeIndex].begin(),tree[2 * treeIndex].end(), queryStart) - tree[2 * treeIndex].begin()) and M to last_in_query_range - first_in_query_range

• Check IF M greater than equals to key then return calculateKSmallest(startIndex, mid, queryStart,queryEnd, 2 * treeIndex, key, tree)

• ELSE, then return calculateKSmallest(mid + 1, endIndex, queryStart, queryEnd, 2 * treeIndex + 1, key - M, tree).

• Inside the function int queryWrapper(int queryStart, int queryEnd, int key, int n, vector<pair<int, int> > &a, vector<int>tree[])

• return call to the function calculateKSmallest(0, n - 1, queryStart - 1, queryEnd - 1, 1, key, tree)

## Example

#include <bits/stdc++.h>
using namespace std;
const int MAX = 1000;
void generateTree(int treeIndex, int leftIndex, int rightIndex, vector<pair<int, int> > &a, vector<int> tree[]){
if (leftIndex == rightIndex){
tree[treeIndex].push_back(a[leftIndex].second);
return;
}
int midValue = (leftIndex + rightIndex) / 2;
generateTree(2 * treeIndex, leftIndex, midValue, a, tree);
generateTree(2 * treeIndex + 1, midValue + 1, rightIndex, a, tree);
merge(tree[2 * treeIndex].begin(), tree[2 * treeIndex].end(), tree[2 * treeIndex + 1].begin(),
tree[2 * treeIndex + 1].end(), back_inserter(tree[treeIndex]));
}
int calculateKSmallest(int startIndex, int endIndex, int queryStart, int queryEnd, int treeIndex, int key, vector<int> tree[]){
if (startIndex == endIndex){
return tree[treeIndex][0];
}
int mid = (startIndex + endIndex) / 2;
int last_in_query_range = (upper_bound(tree[2 * treeIndex].begin(), tree[2 * treeIndex].end(), queryEnd) - tree[2 * treeIndex].begin());
int first_in_query_range = (lower_bound(tree[2 * treeIndex].begin(), tree[2 * treeIndex].end(),queryStart) - tree[2 * treeIndex].begin());
int M = last_in_query_range - first_in_query_range;
if (M >= key){
return calculateKSmallest(startIndex, mid, queryStart, queryEnd, 2 * treeIndex, key, tree);
}
else {
return calculateKSmallest(mid + 1, endIndex, queryStart,queryEnd, 2 * treeIndex + 1, key - M, tree);
}
}
int queryWrapper(int queryStart, int queryEnd, int key, int n,
vector<pair<int, int> > &a, vector<int> tree[]){
return calculateKSmallest(0, n - 1, queryStart - 1, queryEnd - 1, 1, key, tree);
}
int main(){
int input[] = { 7, 8 , 1, 4 , 6 , 8 , 10 };
int size = sizeof(input)/sizeof(input[0]);
vector<pair<int, int> > vec;
for (int i = 0; i < size; i++) {
vec.push_back(make_pair(input[i], i));
}
sort(vec.begin(), vec.end());
vector<int> tree[MAX];
generateTree(1, 0, size - 1, vec, tree);

cout<<"Count of number which are smaller than or equal to key value in the given range are:"<<endl;

int getSmallestIndex = queryWrapper(2, 4, 2, size, vec, tree);
cout << input[getSmallestIndex] << endl;
getSmallestIndex = queryWrapper(1, 6, 3, size, vec, tree);
cout << input[getSmallestIndex] << endl;
return 0;
}

## Output

If we run the above code it will generate the following Output

Count of number which are smaller than or equal to key value in the given range are:
4
6