给定一个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