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
- Find GCD of each subtree of a given node in an N-ary Tree for Q queries
- Queries for M-th node in the DFS of subtree
- Convert a Binary Tree such that every node stores the sum of all nodes in its right subtree
- Count of distinct colors in a subtree of a Colored Tree with given min frequency for Q queries
- Queries for DFS of a subtree in a tree
- 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
- Count pairs having Bitwise XOR less than K from given array
- 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

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.