You are given an **n-ary tree** with a special **property**: If we burst a random node of the tree, this node along with its immediate parents up to the root vanishes. The tree has N nodes and nodes are numbered from 1 to N. The root is always at 1. Given a sequence of **queries ** denoting the number of the node we start bursting, the problem is to find the number of subtrees that would be formed in the end according to the above property, for each query independently.

Examples:

Input: Consider the following tree: 1 / | \ 2 3 4 / \ \ 5 6 7 / \ 8 9 q = 2 n = 1 n = 7 Output: 3 4 Explanation: In the first query after bursting node 1, there will be 3 subtrees formed rooted at 2, 3 and 4. In the second query after bursting node 7, nodes 4 and 1 also get burst, thus there will be 4 subtrees formed rooted at 8, 9, 2 and 3.

Since we are dealing with n-ary tree we can use a representation similar to that of a **graph**, and add the bidirectional edges in an array of lists. Now if we burst a node, we can say for sure that all its children will become separate subtrees. Moreover all the children of its parents and others ancestors till the root that burst, will also become separate subtrees. So in our final answer we want to **exclude** the current node and all its ancestors in the path till the root. Thus we can form the **equation** to solve as:

answer[node] = degree[node] + allChild[parent[node]] – countPath[node]

where allChild[]: number of node’s children + number of its

parent’s children + ..+ number of root’s children

parent[]: parent of a node in the tree

degree[]: number of children for a node

countPath[]: number of nodes from root to parent of node

We can fill all the above arrays using **depth first search** over the adjacency list.We can start from the root 1, assuming its parent is 0 and recur depth first to propagate its values to its children. Thus we can pre-process and fill the above arrays initially and return the equation’s value for each query accordingly.

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

`// CPP program to find number of subtrees after bursting nodes ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// do depth first search of node nod; par is its parent ` `void` `dfs(` `int` `nod, ` `int` `par, list<` `int` `> adj[], ` `int` `allChild[], ` ` ` `int` `parent[], ` `int` `degree[], ` `int` `countPath[]) ` `{ ` ` ` `// go through the adjacent nodes ` ` ` `for` `(` `auto` `it = adj[nod].begin(); it != adj[nod].end(); it++) { ` ` ` `int` `curr = *it; ` ` ` ` ` `// avoid cycling ` ` ` `if` `(curr == par) ` ` ` `continue` `; ` ` ` ` ` `degree[nod]++; ` ` ` `countPath[curr] = countPath[nod] + 1; ` ` ` `parent[curr] = nod; ` ` ` `} ` ` ` ` ` `// propagated from parent ` ` ` `allChild[nod] = allChild[parent[nod]] + degree[nod]; ` ` ` ` ` `// go through the adjacent nodes ` ` ` `for` `(` `auto` `it = adj[nod].begin(); it != adj[nod].end(); it++) { ` ` ` `int` `curr = *it; ` ` ` ` ` `// avoid cycling ` ` ` `if` `(curr == par) ` ` ` `continue` `; ` ` ` ` ` `// recur and go depth first ` ` ` `dfs(curr, nod, adj, allChild, parent, degree, countPath); ` ` ` `} ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `int` `n = 9; ` ` ` ` ` `// adjacency list for each node ` ` ` `list<` `int` `> adj[n + 1]; ` ` ` ` ` `// allChild[]: number of node's children + number of its ` ` ` `// parent's children + ..+ number of root's children ` ` ` `// parent[]: parent of a node in the tree ` ` ` `// degree[]: number of children for a node ` ` ` `// countPath[]: number of nodes from root to parent of node ` ` ` `int` `allChild[n + 1] = { 0 }, parent[n + 1] = { 0 }, ` ` ` `degree[n + 1] = { 0 }, countPath[n + 1] = { 0 }; ` ` ` ` ` `// construct tree ` ` ` `adj[1].push_back(2); ` ` ` `adj[2].push_back(1); ` ` ` `adj[1].push_back(3); ` ` ` `adj[3].push_back(1); ` ` ` `adj[1].push_back(4); ` ` ` `adj[4].push_back(1); ` ` ` `adj[3].push_back(5); ` ` ` `adj[5].push_back(3); ` ` ` `adj[3].push_back(6); ` ` ` `adj[6].push_back(3); ` ` ` `adj[4].push_back(7); ` ` ` `adj[7].push_back(4); ` ` ` `adj[7].push_back(8); ` ` ` `adj[8].push_back(7); ` ` ` `adj[7].push_back(9); ` ` ` `adj[9].push_back(7); ` ` ` ` ` `// assume 1 is root and 0 is its parent ` ` ` `dfs(1, 0, adj, allChild, parent, degree, countPath); ` ` ` ` ` `// 2 queries ` ` ` `int` `curr = 1; ` ` ` `cout << degree[curr] + allChild[parent[curr]] - countPath[curr] << endl; ` ` ` ` ` `curr = 7; ` ` ` `cout << degree[curr] + allChild[parent[curr]] - countPath[curr] << endl; ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

Output:

3

4

The **time complexity** of the above algorithm is O(E * lg(V)) where E id the number of edges and

V is the number of vertices.

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:

- Calculate number of nodes in all subtrees | Using DFS
- Count of subtrees from an N-ary tree consisting of single colored nodes
- Find Count of Single Valued Subtrees
- Find largest subtree having identical left and right subtrees
- Check if a Binary Tree contains duplicate subtrees of size 2 or more
- Number of subtrees having odd count of even numbers
- Find All Duplicate Subtrees
- Count subtrees that sum up to a given value x only using single recursive function
- Count of subtrees in a Binary Tree having XOR value K
- Count of subtrees in a Binary Tree having bitwise OR value K
- Print updated levels of each node of a Complete Binary Tree based on difference in weights of subtrees
- Maximum length cycle that can be formed by joining two nodes of a binary tree
- Print the Forests of a Binary Tree after removal of given Nodes
- Print levels with odd number of nodes and even number of nodes
- Sum of all odd nodes in the path connecting two given nodes
- Common nodes in the inorder sequence of a tree between given two nodes in O(1) space
- Minimum number of Nodes to be removed such that no subtree has more than K nodes
- Count the nodes of the tree which make a pangram when concatenated with the sub-tree nodes
- Count of all prime weight nodes between given nodes in the given Tree
- Sum of all the numbers that are formed from root to leaf paths

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.