给定一个 N 元树和Q查询,其中每个查询包含 N 元树的一个节点,任务是计算 Q 查询子树中具有奇数除数的节点的数量。
例子:
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.
朴素的方法:一个简单的解决方案是遍历每个查询的子树并找到具有奇数除数的节点数。
有效的方法:这个想法是预先计算每个子树的奇数除数的计数并将计数存储在哈希映射中。为了预先计算具有奇数除数的节点数,我们可以使用深度优先搜索遍历。最后,为了检查当前节点是否有奇数个除数,我们可以使用每个完全平方数都有一个奇数个除数的事实。
下面是上述方法的实现:
C++
// C++ implementation to count the
// number of nodes havving odd
// number of divisors for each query
#include
using namespace std;
#define N 100001
// Adjacency list
// for tree.
vector adj[N];
// Array for values and
// answer at ith node.
int a[N], ans[N];
// Function to check whether N
// has odd divisors or not
bool hasOddNumberOfDivisors(int n)
{
if ((double)sqrt(n) == (int)sqrt(n))
return true;
return false;
}
// DFS function to pre-compute
// the answers
int dfs(int node, int parent)
{
// Initialize the count
int count = 0;
for (auto i = adj[node].begin(); i != adj[node].end();
++i) {
if (*i != parent) {
// Repeat for every child
count += dfs(*i, node);
}
}
// Increase the count if current node
// has odd number of divisors
if (hasOddNumberOfDivisors(a[node]))
++count;
ans[node] = count;
return count;
}
// Driver Code
int main()
{
int n = 5, i;
vector q = { 4, 1, 5, 3 };
// Adjacency List
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;
// Function call
dfs(1, -1);
for (int i = 0; i < q.size(); i++) {
cout << ans[q[i]] << " ";
}
return 0;
}
Java
// Java implementation to
// count the number of nodes
// havving odd number of
// divisors for each query
import java.util.*;
class GFG{
static final int N = 100001;
// Adjacency list
// for tree.
static Vector []adj =
new Vector[N];
// Array for values and
// answer at ith node.
static int []a = new int[N];
static int []ans = new int[N];
// Function to check whether N
// has odd divisors or not
static boolean hasOddNumberOfDivisors(int n)
{
if ((double)Math.sqrt(n) ==
(int)Math.sqrt(n))
return true;
return false;
}
// DFS function to
// pre-compute the answers
static int dfs(int node,
int parent)
{
// Initialize the count
int count = 0;
for (int i : adj[node])
{
if (i != parent)
{
// Repeat for every child
count += dfs(i, node);
}
}
// Increase the count if
// current node has odd
// number of divisors
if (hasOddNumberOfDivisors(a[node]))
++count;
ans[node] = count;
return count;
}
// Driver Code
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();
// Adjacency List
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;
// Function call
dfs(1, -1);
for (int i = 0; i < q.length; i++)
{
System.out.print(ans[q[i]] + " ");
}
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 implementation to count the
# number of nodes havving odd
# number of divisors for each query
import math
N = 100001
# Adjacency list
# for tree.
adj = [[] for i in range(N)]
# Array for values and
# answer at ith node.
a = [0 for i in range(N)]
ans = [0 for i in range(N)]
# Function to check whether N
# has odd divisors or not
def hasOddNumberOfDivisors(n):
if (math.sqrt(n) == int(math.sqrt(n))):
return True
return False
# DFS function to pre-compute
# the answers
def dfs(node, parent):
# Initialize the count
count = 0
for i in adj[node]:
if (i != parent):
# Repeat for every child
count += dfs(i, node)
# Increase the count if current node
# has odd number of divisors
if (hasOddNumberOfDivisors(a[node])):
count += 1
ans[node] = count
return count
# Driver Code
if __name__=="__main__":
n = 5
i = 0
q = [ 4, 1, 5, 3 ]
# Adjacency List
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
# Function call
dfs(1, -1)
for i in range(len(q)):
print(ans[q[i]], end = ' ')
# This code is contributed by rutvik_56
C#
// C# implementation to
// count the number of nodes
// havving odd number of
// divisors for each query
using System;
using System.Collections.Generic;
class GFG{
static readonly int N = 100001;
// Adjacency list
// for tree.
static List []adj =
new List[N];
// Array for values and
// answer at ith node.
static int []a = new int[N];
static int []ans = new int[N];
// Function to check whether N
// has odd divisors or not
static bool hasOddNumberOfDivisors(int n)
{
if ((double)Math.Sqrt(n) ==
(int)Math.Sqrt(n))
return true;
return false;
}
// DFS function to
// pre-compute the answers
static int dfs(int node,
int parent)
{
// Initialize the count
int count = 0;
foreach (int i in adj[node])
{
if (i != parent)
{
// Repeat for every child
count += dfs(i, node);
}
}
// Increase the count if
// current node has odd
// number of divisors
if (hasOddNumberOfDivisors(a[node]))
++count;
ans[node] = count;
return count;
}
// Driver Code
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();
// Adjacency List
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;
// Function call
dfs(1, -1);
for (int i = 0;
i < q.Length; i++)
{
Console.Write(ans[q[i]] + " ");
}
}
}
// This code is contributed by Rajput-Ji
1 3 0 1
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live