Related Articles

# Merge Sort Tree (Smaller or equal elements in given row range)

• Difficulty Level : Hard
• Last Updated : 14 Jun, 2017

Given an array where each element is a vector containing integers in sorted order. The task is to answer following queries:

```
count(start, end, k) : Count the numbers smaller than or equal
to k in range from array index 'start'
to 'end'.
```

For convenience we consider an n * n 2-D array where each row corresponds to an integer vector.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Examples:

```Input : ar[][] = {{2, 4, 5},
{3, 4, 9},
{6, 8, 10}}

Queries[] = (0, 1, 5)
(1, 2, 1)
(0, 2, 6)
Output : 5
0
6
Count of elements (smaller than or equal to 5) from
1st row (index 0) to 2nd row (index 1) is 5.
Count of elements (smaller than or equal to 1) from
2nd row to 3nd row is 0
Count of elements (smaller than or equal to 6) from
1st row to 3nd row is 6.
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

The key idea is to build a Segment Tree with a vector at every node and the vector contains all the elements of the sub-range in a sorted order. And if we observe this segment tree structure this is somewhat similar to the tree formed during the merge sort algorithm(that is why it is called merge sort tree)

 `// C++ program to count number of smaller or``// equal to given number and given row range.``#include``using` `namespace` `std;`` ` `const` `int` `MAX = 1000;`` ` `// Constructs a segment tree and stores sTree[]``void` `buildTree(``int` `idx, ``int` `ss, ``int` `se, vector<``int``> a[],``                                  ``vector<``int``> sTree[])``{``    ``/*leaf node*/``    ``if` `(ss == se)``    ``{``        ``sTree[idx] = a[ss];``        ``return``;``    ``}`` ` `    ``int` `mid = (ss+se)/2;`` ` `    ``/* building left subtree */``    ``buildTree(2*idx+1, ss, mid, a, sTree);`` ` `    ``/* building right subtree */``    ``buildTree(2*idx+2, mid+1, se, a, sTree);`` ` `    ``/* merging left and right child in sorted order */``    ``merge(sTree[2*idx+1].begin(), sTree[2*idx+1].end(),``          ``sTree[2*idx+2].begin(), sTree[2*idx+2].end(),``          ``back_inserter(sTree[idx]));``}`` ` `// Recursive function to count smaller elements from row``// a[ss] to a[se] and value smaller than or equal to k.``int` `queryRec(``int` `node, ``int` `start, ``int` `end, ``int` `ss, ``int` `se,``         ``int` `k, vector<``int``> a[], vector<``int``> sTree[])``{``    ``/* If out of range return 0 */``    ``if` `(ss > end || start > se)``        ``return` `0;`` ` `    ``/* if inside the range return count */``    ``if` `(ss <= start && se >= end)``    ``{``        ``/* binary search over the sorted vector``           ``to return count >= X */``        ``return` `upper_bound(sTree[node].begin(),``                           ``sTree[node].end(), k) -``                           ``sTree[node].begin();``    ``}`` ` `    ``int` `mid = (start+end)/2;`` ` `    ``/*searching in left subtree*/``    ``int` `p1 = queryRec(2*node+1, start, mid, ss, se, k, a, sTree);`` ` `    ``/*searching in right subtree*/``    ``int` `p2 = queryRec(2*node+2, mid+1, end, ss, se, k, a, sTree);`` ` `    ``/*adding both the result*/``    ``return` `p1 + p2;``}`` ` `// A wrapper over query().``int` `query(``int` `start, ``int` `end, ``int` `k, vector<``int``> a[], ``int` `n,``                                  ``vector<``int``> sTree[])``{``   ``return` `queryRec(0, 0, n-1, start, end, k, a, sTree);``}`` ` `// Driver code``int` `main()``{``    ``int` `n = 3;``    ``int` `arr[] = { {2, 4, 5},``                     ``{3, 4, 9},``                     ``{6, 8, 10}};`` ` `    ``// build an array of vectos from above input``    ``vector<``int``> a[n];``    ``for` `(``int` `i=0; i sTree[MAX];``    ``buildTree(0, 0, n-1, a, sTree);`` ` `    ``/* un-comment to print merge sort tree*/``    ``/*for (int i=0;i<2*n-1;i++)``    ``{``        ``cout << i << "  ";``        ``for (int j=0;j

Output:

```5
0
6
```

buildTree() analysis : Build a merge sort tree takes O(N log N) time which is same as Merge Sort Algorithm. It also takes O(n log n) extra space.

query() analysis :
A range ‘start’ to ‘end’ can divided into at most Log(n) parts, where we will perform binary search on each part . Binary search requires O(Log n). Therefore total complexity O(Log n * Log n).

This article is contributed by Vineet Jha. 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.