Given a rooted tree (assume root is **1**) of **N** nodes and **Q** queries, each of the form **(Val, Node)**. For each query, the task is to find the number of nodes with values smaller than **Val** in sub-tree of **Node**, including itself.

Note that by definition, nodes in this tree are unique.

**Examples:**

Input:N = 7, Q = 3 Val = 4, Node = 4 Val = 7, Node = 6 Val = 5, Node = 1 Given tree:Output:2 1 4Explanation:For given queries: Q1 -> Val = 4, Node = 4 The required nodes are 2 and 3 Hence the output is 2 Q2 -> Val = 7, Node = 6 The required node is 6 only Hence the output is 1 Q3 -> Val = 5, Node = 1 The required nodes are 1, 2, 3 and 4 Hence the output is 4

**Naive approach:** A simple approach to solve this problem would be to run DFS from a given node for each query and count the number of nodes smaller than the given value. The parent of a given node must be excluded from the DFS.

**Time complexity:** **O(N*Q)**, where **Q** is the number of queries and **N** is the number of nodes in the tree.

**Efficient Approach:** We can reduce the problem of finding the number of elements in a sub-tree to finding them in contiguous segments of an array. To generate such a representation we run a DFS from the root node and push the node into an array when we enter into it the first time and while exiting for the last time. This representation of a tree is known as Euler Tour of the tree.

For example,

The Euler Tour of the above tree will be:

1 4 2 2 3 3 5 5 4 6 7 7 6 1

This representation of tree has the property that the sub-tree of every node **X** is contained within the first and last occurrence of **X** in the array. Each node appears exactly twice. So counting the number of nodes smaller than **Val** between the first and last occurrence of **Node** will give us twice the answer of that query.

Using this representation, the queries can be processed offline in **O(log(N))** per query using a binary indexed tree.

**Pre-processing:**

- We store the index of 1st and last occurrence of each node in the Tour in two arrays,
**start**and**end**. Let**start[X]**and**end[X]**represent these indices for node**X**. This can be done in**O(N)** - In the Euler Tour we store the position of the element along with node as a pair
**(indexInTree, indexInTour)**, and then sort according to**indexInTree**. Let this array be**sortedTour** - Similarly, we maintain an array of Queries of the form
**(Val, Node)**and sort according to**Val**. Let this array be**sortedQuery** - Initialize a Binary Indexed Tree of size
**2N**with all entries as 0. Let this be**bit** - Then proceed as follows. Maintain a pointer each in
**sortedTour**and**sortedQuery** - For each query in
**sortedQuery**from the beginning select the nodes from**sortedTour**having**indexInTree < Val**, and increment their**indexInTour**in**bit**. Then the answer of that query would be half of the sum from**start[Node]**to**end[Node]** - For the next query in
**sortedQuery**we select any previously un-selected nodes from**sortedTour**having**indexInTree < Val**, and increment their**indexInTour**in**bit**and answer the query as done before. - Repeating this process for each query we can answer them in
**O(Qlog(N)).**

Below is the C++ implementation of the above approach:

`// C++ program Queries to find the Number of ` `// Nodes having Smaller Values from a Given ` `// Value in the Subtree of a Node ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// Takes a tree and generates a Euler tour for that ` `// tree in 'tour' parameter This is a modified form ` `// of DFS in which we push the node while entering for ` `// the first time and when exiting from it ` `void` `eulerTour(vector<vector<` `int` `> >& tree, ` ` ` `vector<` `int` `>& vst, ` ` ` `int` `root, ` ` ` `vector<` `int` `>& tour) ` `{ ` ` ` ` ` `// Push node in tour while entering ` ` ` `tour.push_back(root); ` ` ` ` ` `// DFS ` ` ` `vst[root] = 1; ` ` ` `for` `(` `auto` `& x : tree[root]) { ` ` ` `if` `(!vst[x]) { ` ` ` `eulerTour(tree, vst, x, tour); ` ` ` `} ` ` ` `} ` ` ` ` ` `// Push ndode in tour while exiting ` ` ` `tour.push_back(root); ` `} ` ` ` `// Creates the start and end array as described in ` `// pre-processing section. Traverse the tour from ` `// left to right and update start for 1st occurrence ` `// and end for 2nd occurrence of each node ` `void` `createStartEnd(vector<` `int` `>& tour, ` ` ` `vector<` `int` `>& start, ` ` ` `vector<` `int` `>& end) ` `{ ` ` ` `for` `(` `int` `i = 1; i < tour.size(); ++i) { ` ` ` `if` `(start[tour[i]] == -1) { ` ` ` `start[tour[i]] = i; ` ` ` `} ` ` ` `else` `{ ` ` ` `end[tour[i]] = i; ` ` ` `} ` ` ` `} ` `} ` ` ` `// Returns a sorted array of pair containing node and ` `// tourIndex as described in pre-processing section ` `vector<pair<` `int` `, ` `int` `> > ` `createSortedTour(vector<` `int` `>& tour) ` `{ ` ` ` `vector<pair<` `int` `, ` `int` `> > arr; ` ` ` `for` `(` `int` `i = 1; i < tour.size(); ++i) { ` ` ` `arr.push_back(make_pair(tour[i], i)); ` ` ` `} ` ` ` `sort(arr.begin(), arr.end()); ` ` ` `return` `arr; ` `} ` ` ` `// Binary Indexed Tree Implementation ` `// This function will add 1 from the position ` `void` `increment(vector<` `int` `>& bit, ` `int` `pos) ` `{ ` ` ` `for` `(; pos < bit.size(); pos += pos & -pos) { ` ` ` `bit[pos]++; ` ` ` `} ` `} ` ` ` `// It will give the range sum ` `int` `query(vector<` `int` `>& bit, ` ` ` `int` `start, ` ` ` `int` `end) ` `{ ` ` ` `--start; ` ` ` `int` `s1 = 0, s2 = 0; ` ` ` `for` `(; start > 0; start -= start & -start) { ` ` ` `s1 += bit[start]; ` ` ` `} ` ` ` `for` `(; end > 0; end -= end & -end) { ` ` ` `s2 += bit[end]; ` ` ` `} ` ` ` `return` `s2 - s1; ` `} ` ` ` `// Function to caluculate the ans for each query ` `map<pair<` `int` `, ` `int` `>, ` `int` `> cal(` `int` `N, ` ` ` `int` `Q, ` ` ` `vector<vector<` `int` `>> tree, ` ` ` `vector<pair<` `int` `, ` `int` `>> queries) ` `{ ` ` ` `// Preprocessing ` ` ` `// Creating the vector to store the tours and queries ` ` ` `vector<` `int` `> tour, vst(N + 1, 0), ` ` ` `start(N + 1, -1), ` ` ` `end(N + 1, -1), ` ` ` `bit(2 * N + 4, 0); ` ` ` ` ` `// For one based indexing in tour. ` ` ` `// Simplifies code for Binary Indexed Tree. ` ` ` `// We will ignore the 1st element in tour ` ` ` `tour.push_back(-1); ` ` ` ` ` `// Create Euler Tour ` ` ` `eulerTour(tree, vst, 1, tour); ` ` ` ` ` `// Create Start and End Array ` ` ` `createStartEnd(tour, start, end); ` ` ` ` ` `// Create sortedTour and sortedQuery ` ` ` `auto` `sortedTour = createSortedTour(tour); ` ` ` ` ` `auto` `sortedQuery = queries; ` ` ` ` ` `sort(sortedQuery.begin(), sortedQuery.end()); ` ` ` ` ` `// For storing answers to query ` ` ` `map<pair<` `int` `, ` `int` `>, ` `int` `> queryAns; ` ` ` ` ` `// We maintain pointers each for sortedTour and ` ` ` `// sortedQuery.For each element X in sortedTour ` ` ` `// we first process any queries with val smaller ` ` ` `// than X's node and update queryptr to first ` ` ` `// unprocessed query.Then update the position ` ` ` `// of X in BIT. ` ` ` ` ` `int` `tourptr = 0, queryptr = 0; ` ` ` `while` `(queryptr < sortedQuery.size()) { ` ` ` ` ` `// Queries lies in the range then ` ` ` `while` `(queryptr < sortedQuery.size() ` ` ` `&& sortedQuery[queryptr].first ` ` ` `<= sortedTour[tourptr].first){ ` ` ` ` ` `auto` `node = sortedQuery[queryptr].second; ` ` ` ` ` `// Making the query on BIT and dividing by 2. ` ` ` `queryAns[sortedQuery[queryptr]] ` ` ` `= query(bit, start[node], end[node]) / 2; ` ` ` `++queryptr; ` ` ` `} ` ` ` `if` `(tourptr < sortedTour.size()) { ` ` ` `increment(bit, sortedTour[tourptr].second); ` ` ` `++tourptr; ` ` ` `} ` ` ` `} ` ` ` ` ` `return` `queryAns; ` `} ` ` ` `// Driver Code ` `int` `main() ` `{ ` ` ` ` ` `int` `N = 7, Q = 3; ` ` ` ` ` `// Tree edges ` ` ` `vector<vector<` `int` `> > tree = { {}, ` ` ` `{ 4, 6 }, ` ` ` `{ 4 }, ` ` ` `{ 4 }, ` ` ` `{ 1, 2, 3, 5 }, ` ` ` `{ 4 }, ` ` ` `{ 1, 7 }, ` ` ` `{ 6 } }; ` ` ` ` ` `// Queries vector ` ` ` `vector<pair<` `int` `, ` `int` `> > queries ` ` ` `= { make_pair(4, 1), ` ` ` `make_pair(7, 6), ` ` ` `make_pair(5, 1) }; ` ` ` ` ` `// Calling the function ` ` ` `map<pair<` `int` `, ` `int` `>, ` `int` `> queryAns = ` ` ` `cal(N, Q, tree, queries); ` ` ` ` ` `// Print answer in order of input. ` ` ` `for` `(` `auto` `& x : queries) { ` ` ` `cout << queryAns[x] << ` `'\n'` `; ` ` ` `} ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

3 1 4

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.

## Recommended Posts:

- Node having maximum number of nodes less than its value in its subtree
- Count of nodes having odd divisors in the given subtree for Q queries
- Minimum number of Nodes to be removed such that no subtree has more than K nodes
- Queries to find the Minimum Weight from a Subtree of atmost D-distant Nodes from Node X
- Sum of all array elements less than X and greater than Y for Q queries
- Queries for M-th node in the DFS of subtree
- Find GCD of each subtree of a given node in an N-ary Tree for Q queries
- Convert a Binary Tree such that every node stores the sum of all nodes in its right subtree
- Queries for DFS of a subtree in a tree
- Count of distinct colors in a subtree of a Colored Tree with given min frequency for Q queries
- Subtree of all nodes in a tree using DFS
- Count of subsets having sum of min and max element less than K
- First element of every K sets having consecutive elements with exactly K prime factors less than N
- Queries for elements having values within the range A to B in the given index range using Segment Tree
- Queries for elements having values within the range A to B using MO's Algorithm
- Find the Kth node in the DFS traversal of a given subtree in a Tree
- Number of elements less than or equal to a given number in a given subarray
- Number of elements less than or equal to a given number in a given subarray | Set 2 (Including Updates)
- Number of elements less than or equal to a number in a subarray : MO's Algorithm
- Querying the number of distinct colors in a subtree of a colored tree using BIT

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.