Find the number of pair of Ideal nodes in a given tree
Last Updated :
05 Oct, 2021
Given a tree of N nodes and an integer K, each node is numbered between 1 and N. The task is to find the number of pairs of ideal nodes in a tree.
A pair of nodes (a, b) is called ideal if
- a is an ancestor of b.
- And, abs(a - b) ? K
Examples:
Input:

K = 2
Output: 4
(1, 2), (1, 3), (3, 4), (3, 5) are such pairs.
Input: Consider the graph in example 1 and k = 3
Output: 6
(1, 2), (1, 3), (1, 4), (3, 4), (3, 5), (3, 6) are such pairs.
Approach: First, we need to traverse the tree using DFS so we need to find the root node, the node without a parent. As we traverse each node we will store it in a data structure to keep track of all the ancestors for the next node. Before doing that, get the number of the node's ancestors in the range [presentNode - k, presentNode + k] then add it to the total pairs.
We need a data structure which can:
- Insert a node as we traverse the tree.
- Remove a node as we return.
- Give the number of nodes within the range [presentNode - k, PresentNode + k] which were stored.
Binary indexed tree fulfills the above three operations.
We can do the above 3 operations by initializing all the index values of the BIT to 0 and then:
- Insert a node by updating the index of that node to 1.
- Remove a node by updating the index of that node to 0.
- Get the number of similar pairs of the ancestor of that node by querying for the sum of the range [presentNode - k, PresentNode + k]
Below is the implementation of the above approach:
C++
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int n, k;
// Adjacency list
vector<int> al[N];
long long Ideal_pair;
long long bit[N];
bool root_node[N];
// bit : bit array
// i and j are starting and
// ending index INCLUSIVE
long long bit_q(int i, int j)
{
long long sum = 0ll;
while (j > 0) {
sum += bit[j];
j -= (j & (j * -1));
}
i--;
while (i > 0) {
sum -= bit[i];
i -= (i & (i * -1));
}
return sum;
}
// bit : bit array
// n : size of bit array
// i is the index to be updated
// diff is (new_val - old_val)
void bit_up(int i, long long diff)
{
while (i <= n) {
bit[i] += diff;
i += i & -i;
}
}
// DFS function to find ideal pairs
void dfs(int node)
{
Ideal_pair += bit_q(max(1, node - k),
min(n, node + k));
bit_up(node, 1);
for (int i = 0; i < al[node].size(); i++)
dfs(al[node][i]);
bit_up(node, -1);
}
// Function for initialisation
void initialise()
{
Ideal_pair = 0;
for (int i = 0; i <= n; i++) {
root_node[i] = true;
bit[i] = 0LL;
}
}
// Function to add an edge
void Add_Edge(int x, int y)
{
al[x].push_back(y);
root_node[y] = false;
}
// Function to find number of ideal pairs
long long Idealpairs()
{
// Find root of the tree
int r = -1;
for (int i = 1; i <= n; i++)
if (root_node[i]) {
r = i;
break;
}
dfs(r);
return Ideal_pair;
}
// Driver code
int main()
{
n = 6, k = 3;
initialise();
// Add edges
Add_Edge(1, 2);
Add_Edge(1, 3);
Add_Edge(3, 4);
Add_Edge(3, 5);
Add_Edge(3, 6);
// Function call
cout << Idealpairs();
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG{
static final int N = 100005;
static int n, k;
// Adjacency list
@SuppressWarnings("unchecked")
static Vector<Integer> []al = new Vector[N];
static long Ideal_pair;
static long []bit = new long[N];
static boolean []root_node = new boolean[N];
// bit : bit array
// i and j are starting and
// ending index INCLUSIVE
static long bit_q(int i, int j)
{
long sum = 0;
while (j > 0)
{
sum += bit[j];
j -= (j & (j * -1));
}
i--;
while (i > 0)
{
sum -= bit[i];
i -= (i & (i * -1));
}
return sum;
}
// bit : bit array
// n : size of bit array
// i is the index to be updated
// diff is (new_val - old_val)
static void bit_up(int i, long diff)
{
while (i <= n)
{
bit[i] += diff;
i += i & -i;
}
}
// DFS function to find ideal pairs
static void dfs(int node)
{
Ideal_pair += bit_q(Math.max(1, node - k),
Math.min(n, node + k));
bit_up(node, 1);
for(int i = 0; i < al[node].size(); i++)
dfs(al[node].get(i));
bit_up(node, -1);
}
// Function for initialisation
static void initialise()
{
Ideal_pair = 0;
for (int i = 0; i <= n; i++) {
root_node[i] = true;
bit[i] = 0;
}
}
// Function to add an edge
static void Add_Edge(int x, int y)
{
al[x].add(y);
root_node[y] = false;
}
// Function to find number of ideal pairs
static long Idealpairs()
{
// Find root of the tree
int r = -1;
for(int i = 1; i <= n; i++)
if (root_node[i])
{
r = i;
break;
}
dfs(r);
return Ideal_pair;
}
// Driver code
public static void main(String[] args)
{
n = 6;
k = 3;
for(int i = 0; i < al.length; i++)
al[i] = new Vector<Integer>();
initialise();
// Add edges
Add_Edge(1, 2);
Add_Edge(1, 3);
Add_Edge(3, 4);
Add_Edge(3, 5);
Add_Edge(3, 6);
// Function call
System.out.print(Idealpairs());
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 implementation of the approach
N = 100005
Ideal_pair = 0
# Adjacency list
al = [[] for i in range(100005)]
bit = [0 for i in range(N)]
root_node = [0 for i in range(N)]
# bit : bit array
# i and j are starting and
# ending index INCLUSIVE
def bit_q(i, j):
sum = 0
while (j > 0):
sum += bit[j]
j -= (j & (j * -1))
i -= 1
while (i > 0):
sum -= bit[i]
i -= (i & (i * -1))
return sum
# bit : bit array
# n : size of bit array
# i is the index to be updated
# diff is (new_val - old_val)
def bit_up(i, diff):
while (i <= n):
bit[i] += diff
i += i & -i
# DFS function to find ideal pairs
def dfs(node, x):
Ideal_pair = x
Ideal_pair += bit_q(max(1, node - k),
min(n, node + k))
bit_up(node, 1)
for i in range(len(al[node])):
Ideal_pair = dfs(al[node][i], Ideal_pair)
bit_up(node, -1)
return Ideal_pair
# Function for initialisation
def initialise():
Ideal_pair = 0;
for i in range(n + 1):
root_node[i] = True
bit[i] = 0
# Function to add an edge
def Add_Edge(x, y):
al[x].append(y)
root_node[y] = False
# Function to find number of ideal pairs
def Idealpairs():
# Find root of the tree
r = -1
for i in range(1, n + 1, 1):
if (root_node[i]):
r = i
break
Ideal_pair = dfs(r, 0)
return Ideal_pair
# Driver code
if __name__ == '__main__':
n = 6
k = 3
initialise()
# Add edges
Add_Edge(1, 2)
Add_Edge(1, 3)
Add_Edge(3, 4)
Add_Edge(3, 5)
Add_Edge(3, 6)
# Function call
print(Idealpairs())
# This code is contributed by
# Surendra_Gangwar
C#
// C# implementation of the
// above approach
using System;
using System.Collections.Generic;
class GFG{
static readonly int N = 100005;
static int n, k;
// Adjacency list
static List<int> []al =
new List<int>[N];
static long Ideal_pair;
static long []bit =
new long[N];
static bool []root_node =
new bool[N];
// bit : bit array
// i and j are starting and
// ending index INCLUSIVE
static long bit_q(int i,
int j)
{
long sum = 0;
while (j > 0)
{
sum += bit[j];
j -= (j & (j * -1));
}
i--;
while (i > 0)
{
sum -= bit[i];
i -= (i & (i * -1));
}
return sum;
}
// bit : bit array
// n : size of bit array
// i is the index to be updated
// diff is (new_val - old_val)
static void bit_up(int i,
long diff)
{
while (i <= n)
{
bit[i] += diff;
i += i & -i;
}
}
// DFS function to find
// ideal pairs
static void dfs(int node)
{
Ideal_pair += bit_q(Math.Max(1,
node - k),
Math.Min(n,
node + k));
bit_up(node, 1);
for(int i = 0;
i < al[node].Count; i++)
dfs(al[node][i]);
bit_up(node, -1);
}
// Function for
// initialisation
static void initialise()
{
Ideal_pair = 0;
for (int i = 0; i <= n; i++)
{
root_node[i] = true;
bit[i] = 0;
}
}
// Function to add an edge
static void Add_Edge(int x,
int y)
{
al[x].Add(y);
root_node[y] = false;
}
// Function to find number
// of ideal pairs
static long Idealpairs()
{
// Find root of the tree
int r = -1;
for(int i = 1; i <= n; i++)
if (root_node[i])
{
r = i;
break;
}
dfs(r);
return Ideal_pair;
}
// Driver code
public static void Main(String[] args)
{
n = 6;
k = 3;
for(int i = 0; i < al.Length; i++)
al[i] = new List<int>();
initialise();
// Add edges
Add_Edge(1, 2);
Add_Edge(1, 3);
Add_Edge(3, 4);
Add_Edge(3, 5);
Add_Edge(3, 6);
// Function call
Console.Write(Idealpairs());
}
}
// This code is contributed by Amit Katiyar
JavaScript
<script>
// Javascript implementation of the approach
let N = 100005;
let n, k;
// Adjacency list
let al = new Array(N).fill(0).map((t) => []);
let Ideal_pair;
let bit = new Array(N);
let root_node = new Array(N);
// bit : bit array
// i and j are starting and
// ending index INCLUSIVE
function bit_q(i, j) {
let sum = 0;
while (j > 0) {
sum += bit[j];
j -= (j & (j * -1));
}
i--;
while (i > 0) {
sum -= bit[i];
i -= (i & (i * -1));
}
return sum;
}
// bit : bit array
// n : size of bit array
// i is the index to be updated
// diff is (new_val - old_val)
function bit_up(i, diff) {
while (i <= n) {
bit[i] += diff;
i += i & -i;
}
}
// DFS function to find ideal pairs
function dfs(node) {
Ideal_pair += bit_q(Math.max(1, node - k),
Math.min(n, node + k));
bit_up(node, 1);
for (let i = 0; i < al[node].length; i++)
dfs(al[node][i]);
bit_up(node, -1);
}
// Function for initialisation
function initialise() {
Ideal_pair = 0;
for (let i = 0; i <= n; i++) {
root_node[i] = true;
bit[i] = 0;
}
}
// Function to add an edge
function Add_Edge(x, y) {
al[x].push(y);
root_node[y] = false;
}
// Function to find number of ideal pairs
function Idealpairs() {
// Find root of the tree
let r = -1;
for (let i = 1; i <= n; i++)
if (root_node[i]) {
r = i;
break;
}
dfs(r);
return Ideal_pair;
}
// Driver code
n = 6, k = 3;
initialise();
// Add edges
Add_Edge(1, 2);
Add_Edge(1, 3);
Add_Edge(3, 4);
Add_Edge(3, 5);
Add_Edge(3, 6);
// Function call
document.write(Idealpairs());
// This code is contributed by _saurabh_jaiswal
</script>
Time Complexity: O(N*log(N))
Auxiliary Space: O(N)
Similar Reads
Print the number of set bits in each node of a Binary Tree
Given a Binary Tree. The task is to print the number of set bits in each of the nodes in the Binary Tree. The idea is to traverse the given binary tree using any tree traversal method, and for each node calculate the number of set bits and print it. Note: One can also use the __builtin_popcount() fu
6 min read
Number of children of given node in n-ary Tree
Given a node x, find the number of children of x(if it exists) in the given n-ary tree. Example : Input : x = 50 Output : 3 Explanation : 50 has 3 children having values 40, 100 and 20. Approach : Initialize the number of children as 0.For every node in the n-ary tree, check if its value is equal to
7 min read
Find root of n-ary tree from given list of nodes
Given an N-ary tree as a list of nodes Node[] tree. Each node has a unique value, the task is to find the root of the tree. N-ary treeExamples: Input: 1 / | \ 2 3 4 \ 5 Output: Root value is 1 Input: 5 / | \ 3 6 7 / \ / \ 9 2 1 8 Output: Root value is 5 Naive approach: To solve the problem follow th
8 min read
Number of leaf nodes in a perfect N-ary tree of height K
Find the number of leaf nodes in a perfect N-ary tree of height K. Note: As the answer can be very large, return the answer modulo 109+7. Examples: Input: N = 2, K = 2Output: 4Explanation: A perfect Binary tree of height 2 has 4 leaf nodes. Input: N = 2, K = 1Output: 2Explanation: A perfect Binary t
4 min read
Number of nodes greater than a given value in n-ary tree
Given a n-ary tree and a number x, find and return the number of nodes which are greater than x. Example: In the given tree, x = 7 Number of nodes greater than x are 4. Approach: The idea is maintain a count variable initialize to 0. Traverse the tree and compare root data with x. If root data is gr
6 min read
Number of leaf nodes in the subtree of every node of an n-ary tree
Given an N-ary tree, print the number of leaf nodes in the subtree of every node. Examples: Input: 1 / \ 2 3 / | \ 4 5 6 Output: The node 1 has 4 leaf nodes The node 2 has 1 leaf nodes The node 3 has 3 leaf nodes The node 4 has 1 leaf nodes The node 5 has 1 leaf nodes The node 6 has 1 leaf nodes App
8 min read
Count the number of Nodes in a Binary Tree in Constant Space
Given a binary tree having N nodes, count the number of nodes using constant O(1) space. This can be done by simple traversals like- Preorder, InOrder, PostOrder, and LevelOrder but these traversals require an extra space which is equal to the height of the tree. Examples: Input: Output: 5Explanatio
10 min read
Print List of nodes of given n-ary Tree with number of children in range [0, n]
Given an n-ary Tree having N nodes numbered from 1 to N, the task is to print a list of nodes containing 0, 1, 2, 3, . . ., n children. Note: An n-ary Tree is a tree in which nodes can have at most n children. Examples: Input: Output:Â 0 child: 3, 5, 6, 71 child: 42 child: 23 child: 1 Input: Output:
8 min read
Count the number of nodes at given level in a tree using BFS.
Given a tree represented as an undirected graph. Count the number of nodes at a given level l. It may be assumed that vertex 0 is the root of the tree. Examples: Input : 7 0 1 0 2 1 3 1 4 1 5 2 6 2 Output : 4 Input : 6 0 1 0 2 1 3 2 4 2 5 2 Output : 3 BFS is a traversing algorithm that starts traver
9 min read
Count the number of common ancestors of given K nodes in a N-ary Tree
Given an N-ary tree root and a list of K nodes, the task is to find the number of common ancestors of the given K nodes in the tree. Example: Input: root = 3 / \ 2 1 / \ / | \ 9 7 8 6 3K = {7, 2, 9}Output: 2 Explanation: The common ancestors of the nodes 7, 9 and 2 are 2 and 3 Input: root = 2 \ 1 \
10 min read