Count of nodes having odd divisors in the given subtree for Q queries
Last Updated :
19 Apr, 2023
Given a N-ary Tree and Q queries where each query contains a node of the N-ary tree, the task is to count the number of nodes that have an odd number of divisors in the subtree for Q queries.
Examples:
Input:
Output: 1 3 0 1
Explanation:
Query 1: In the subtree rooted at node 100, there is only one node which is 100 which have 9 divisors {1, 2, 4, 5, 10, 20, 25, 50, 100}. Therefore, there is only one node having the odd number of divisors.
Query 2: In the subtree rooted at node 4, there are 5 nodes out of which 3 nodes are having an odd number of divisors. That is {4, 9, 100}
Query 3: In the subtree rooted at node 5, there is only one node which is 5 which has two divisors. Therefore, there zero nodes having an odd number of divisors.
Naive Approach: A simple solution is to traverse the subtree for each query and find the count of nodes that are having an odd number of divisors.
Efficient Approach: The idea is to pre-compute the count of an odd number of divisors for each subtree and storing the count in hash-map. To pre-compute the count of nodes having an odd number of divisors we can use Depth First Search Traversal. Finally, to check that the current node is having an odd number of divisors or not we can use the fact that every perfect square number has an odd number of divisors.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define N 100001
vector< int > adj[N];
int a[N], ans[N];
bool hasOddNumberOfDivisors( int n)
{
if (( double ) sqrt (n) == ( int ) sqrt (n))
return true ;
return false ;
}
int dfs( int node, int parent)
{
int count = 0;
for ( auto i = adj[node].begin(); i != adj[node].end();
++i) {
if (*i != parent) {
count += dfs(*i, node);
}
}
if (hasOddNumberOfDivisors(a[node]))
++count;
ans[node] = count;
return count;
}
int main()
{
int n = 5, i;
vector< int > q = { 4, 1, 5, 3 };
adj[1].push_back(2);
adj[2].push_back(1);
adj[2].push_back(3);
adj[3].push_back(2);
adj[3].push_back(4);
adj[4].push_back(3);
adj[1].push_back(5);
adj[5].push_back(1);
a[1] = 4;
a[2] = 9;
a[3] = 14;
a[4] = 100;
a[5] = 5;
dfs(1, -1);
for ( int i = 0; i < q.size(); i++) {
cout << ans[q[i]] << " " ;
}
return 0;
}
|
Java
import java.util.*;
class GFG{
static final int N = 100001 ;
static Vector<Integer> []adj =
new Vector[N];
static int []a = new int [N];
static int []ans = new int [N];
static boolean hasOddNumberOfDivisors( int n)
{
if (( double )Math.sqrt(n) ==
( int )Math.sqrt(n))
return true ;
return false ;
}
static int dfs( int node,
int parent)
{
int count = 0 ;
for ( int i : adj[node])
{
if (i != parent)
{
count += dfs(i, node);
}
}
if (hasOddNumberOfDivisors(a[node]))
++count;
ans[node] = count;
return count;
}
public static void main(String[] args)
{
int n = 5 ;
int [] q = { 4 , 1 , 5 , 3 };
for ( int i = 0 ; i < adj.length; i++)
adj[i] = new Vector<Integer>();
adj[ 1 ].add( 2 );
adj[ 2 ].add( 1 );
adj[ 2 ].add( 3 );
adj[ 3 ].add( 2 );
adj[ 3 ].add( 4 );
adj[ 4 ].add( 3 );
adj[ 1 ].add( 5 );
adj[ 5 ].add( 1 );
a[ 1 ] = 4 ;
a[ 2 ] = 9 ;
a[ 3 ] = 14 ;
a[ 4 ] = 100 ;
a[ 5 ] = 5 ;
dfs( 1 , - 1 );
for ( int i = 0 ; i < q.length; i++)
{
System.out.print(ans[q[i]] + " " );
}
}
}
|
Python3
import math
N = 100001
adj = [[] for i in range (N)]
a = [ 0 for i in range (N)]
ans = [ 0 for i in range (N)]
def hasOddNumberOfDivisors(n):
if (math.sqrt(n) = = int (math.sqrt(n))):
return True
return False
def dfs(node, parent):
count = 0
for i in adj[node]:
if (i ! = parent):
count + = dfs(i, node)
if (hasOddNumberOfDivisors(a[node])):
count + = 1
ans[node] = count
return count
if __name__ = = "__main__" :
n = 5
i = 0
q = [ 4 , 1 , 5 , 3 ]
adj[ 1 ].append( 2 )
adj[ 2 ].append( 1 )
adj[ 2 ].append( 3 )
adj[ 3 ].append( 2 )
adj[ 3 ].append( 4 )
adj[ 4 ].append( 3 )
adj[ 1 ].append( 5 )
adj[ 5 ].append( 1 )
a[ 1 ] = 4
a[ 2 ] = 9
a[ 3 ] = 14
a[ 4 ] = 100
a[ 5 ] = 5
dfs( 1 , - 1 )
for i in range ( len (q)):
print (ans[q[i]], end = ' ' )
|
C#
using System;
using System.Collections.Generic;
class GFG{
static readonly int N = 100001;
static List< int > []adj =
new List< int >[N];
static int []a = new int [N];
static int []ans = new int [N];
static bool hasOddNumberOfDivisors( int n)
{
if (( double )Math.Sqrt(n) ==
( int )Math.Sqrt(n))
return true ;
return false ;
}
static int dfs( int node,
int parent)
{
int count = 0;
foreach ( int i in adj[node])
{
if (i != parent)
{
count += dfs(i, node);
}
}
if (hasOddNumberOfDivisors(a[node]))
++count;
ans[node] = count;
return count;
}
public static void Main(String[] args)
{
int n = 5;
int [] q = {4, 1, 5, 3};
for ( int i = 0;
i < adj.Length; i++)
adj[i] = new List< int >();
adj[1].Add(2);
adj[2].Add(1);
adj[2].Add(3);
adj[3].Add(2);
adj[3].Add(4);
adj[4].Add(3);
adj[1].Add(5);
adj[5].Add(1);
a[1] = 4;
a[2] = 9;
a[3] = 14;
a[4] = 100;
a[5] = 5;
dfs(1, -1);
for ( int i = 0;
i < q.Length; i++)
{
Console.Write(ans[q[i]] + " " );
}
}
}
|
Javascript
<script>
let N = 100001;
let adj = new Array(N);
let a = new Array(N);
let ans = new Array(N);
function hasOddNumberOfDivisors(n)
{
if (Math.sqrt(n) == parseInt(Math.sqrt(n), 10))
return true ;
return false ;
}
function dfs(node, parent)
{
let count = 0;
for (let i = 0; i < adj[node].length; i++)
{
if (adj[node][i] != parent)
{
count += dfs(adj[node][i], node);
}
}
if (hasOddNumberOfDivisors(a[node]))
++count;
ans[node] = count;
return count;
}
let n = 5;
let q = [4, 1, 5, 3];
for (let i = 0; i < adj.length; i++)
adj[i] = [];
adj[1].push(2);
adj[2].push(1);
adj[2].push(3);
adj[3].push(2);
adj[3].push(4);
adj[4].push(3);
adj[1].push(5);
adj[5].push(1);
a[1] = 4;
a[2] = 9;
a[3] = 14;
a[4] = 100;
a[5] = 5;
dfs(1, -1);
for (let i = 0; i < q.length; i++)
{
document.write(ans[q[i]] + " " );
}
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...