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

📅  最后修改于: 2021-04-24 03:56:22             🧑  作者: 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


输出
1 3 0 1