📌  相关文章
📜  Q 查询的给定子树中具有奇数除数的节点数

📅  最后修改于: 2021-10-27 09:12:08             🧑  作者: Mango

给定一个 N 元树和Q查询,其中每个查询包含 N 元树的一个节点,任务是计算 Q 查询子树中具有奇数除数的节点的数量。

例子:

朴素的方法:一个简单的解决方案是遍历每个查询的子树并找到具有奇数除数的节点数。

有效的方法:这个想法是预先计算每个子树的奇数除数的计数并将计数存储在哈希映射中。为了预先计算具有奇数除数的节点数,我们可以使用深度优先搜索遍历。最后,为了检查当前节点是否有奇数个除数,我们可以使用每个完全平方数都有一个奇数个除数的事实。

下面是上述方法的实现:

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


Javascript


输出
1 3 0 1