# Count of ancestors with smaller value for each node of an N-ary Tree

• Last Updated : 15 Feb, 2022

Given an N-ary tree consisting of N nodes with values from 1 to N rooted at 1, for all nodes, print the number of ancestors having a smaller value than the current node.

Example:

Input: Below is the given Tree:

1
/   \
4     5
/     /  | \
6    3   2  7

Output: 0 1 1 1 1 2 2
Explanation:
Since node 1 is the root node, it has no ancestors.
Ancestors of node 2: {1, 5}. Number of ancestors having value smaller than 2 is 1.
Ancestors of node 3: {1, 5}. Number of ancestors having value smaller than 3 is 1.
Ancestors of node 4: {1}. Number of ancestors having value smaller than 4 is 1.
Ancestors of node 5: {1}. Number of ancestors having value smaller than 5 is 1.
Ancestors of node 6: {1, 4}. Number of ancestors having value smaller than 6 is 2.
Ancestors of node 7: {1, 5}. Number of ancestors having value smaller than 7 is 2

Input: Below is the given Tree:

1
/ \
3   2
\
4

Output: 0 1 1 2
Explanation:
Node 1 has no ancestors.
Ancestors of node 2: {1}. Number of ancestors having value smaller than 2 is 1.
Ancestors of node 3: {1}. Number of ancestors having value smaller than 3 is 1.

Brute Force Approach: The idea is similar to what is mentioned here: Count ancestors with smaller value for each node of a Binary Tree. The idea is to use DFS for each node and can be extended to an N-ary tree easily.

Time Complexity: O(N2)
Auxiliary Space: O(1)

Efficient Approach: The efficient approach is based on the concept of Ordered_set, policy-based data structure, and DFS.

• Use a top-down DFS to traverse from the root to all the nodes and use an ordered set to store values of all nodes in the path from the root to the current node.
• Whenever entering a node, before calling DFS on its children, push the node index into the ordered set and whenever we exit the node, erase the node index from the ordered_set. This ensures that ordered_set will contain values of all ancestors of the current node.
• Since the ordered set gives the functionality to return a number of smaller values than given x by finding the order of the x, for each node, whenever entering the node, simply find the order of the current node’s index and get the number of smaller values present in the ordered_set i.e number of smaller valued ancestors for each node.
• Use a map to store the number of smaller valued ancestors for each node and use that to print the final answer.

Below is the implementation of the above approach.

## C++

 `// C++ program for the above approach``#include `` ` `// Common file``#include `` ` `// Including tree_order_statistics_node_update``#include `` ` `using` `namespace` `std;``using` `namespace` `__gnu_pbds;`` ` `// Declaring ordered_set``typedef` `tree<``int``, null_type, less<``int``>,``             ``rb_tree_tag,``             ``tree_order_statistics_node_update>``    ``ordered_set;`` ` `// Map to store final ans for each node``unordered_map<``int``, ``int``> ans;`` ` `// Function to add an edge``// between nodes u and v``void` `addEdge(vector<``int``> adj[],``             ``int` `u, ``int` `v)``{``    ``adj[u].push_back(v);``    ``adj[v].push_back(u);``}`` ` `// Function to count the number of``// ancestors with values smaller``// than that of the current node``void` `countSmallerAncestors(``    ``vector<``int``> adj[],``    ``int` `root, ``int` `par,``    ``ordered_set& ancestors)``{`` ` `    ``// Map current node to``    ``// number of smaller valued ancestors``    ``ans[root] = ancestors.order_of_key(root);`` ` `    ``// Add current node to path``    ``ancestors.insert(root);``    ``for` `(``int` `node : adj[root]) {`` ` `        ``// Avoid cycles``        ``if` `(node != par) {``            ``countSmallerAncestors(``                ``adj, node,``                ``root, ancestors);``        ``}``    ``}`` ` `    ``// Remove current node from path``    ``ancestors.erase(root);``}`` ` `// Driver Code``int` `main()``{``    ``// Number of nodes in graph``    ``int` `N = 7;`` ` `    ``// Initialize graph``    ``vector<``int``> adj[N + 1];`` ` `    ``// Tree Formation``    ``addEdge(adj, 1, 5);``    ``addEdge(adj, 1, 4);``    ``addEdge(adj, 4, 6);``    ``addEdge(adj, 5, 3);``    ``addEdge(adj, 5, 2);``    ``addEdge(adj, 5, 7);`` ` `    ``// Ordered set to store values in path``    ``// from root to current node in dfs``    ``ordered_set ancestors;`` ` `    ``countSmallerAncestors(adj, 1, -1, ancestors);`` ` `    ``for` `(``int` `i = 1; i <= N; i++) {``        ``cout << ans[i] << ``" "``;``    ``}`` ` `    ``return` `0;``}`

Output:

```0 1 1 1 1 2 2
```

Time Complexity: O(N * log(N)).
Auxiliary Space:  O(N).

My Personal Notes arrow_drop_up