📅  最后修改于: 2023-12-03 15:19:39.644000             🧑  作者: Mango
本题要求在给定的一棵树中,查询子树中具有奇数除数的节点数。这是一道树型动态规划问题,需要用到以下知识点:
我们可以使用深度优先搜索(DFS)遍历整棵树。在遍历每个节点时,我们记录从根节点到该节点的路径上每个节点的值的前缀和。这样,我们就可以快速计算出任何子树的值的前缀和。
然后我们需要计算每个节点的子树中具有奇数除数的节点数量。对于每个节点,我们可以将其子树的前缀和按奇偶性分类,使用前缀和的概念统计每个分类中的节点数量。
最后,我们可以在DFS的过程中,使用一个变量来保存答案,最终返回该变量即可。
class Solution:
def numOfSubtreesWithOddSum(self, n: int, edges: List[List[int]]) -> List[int]:
mod = int(1e9) + 7
# 构建邻接表
graph = [[] for _ in range(n)]
for u, v in edges:
graph[u - 1].append(v - 1)
graph[v - 1].append(u - 1)
# DFS计算前缀和
prefix_sum = [0] * n
def dfs(node, parent):
nonlocal prefix_sum
prefix_sum[node] = (prefix_sum[parent] + node) % 2
odd_cnt = 1 if prefix_sum[node] == 1 else 0
even_cnt = 1 if prefix_sum[node] == 0 else 0
for child in graph[node]:
if child != parent:
dfs(child, node)
odd_cnt += cnt_odd[child]
even_cnt += cnt_even[child]
cnt_odd[node] = odd_cnt
cnt_even[node] = even_cnt
# 计算子树中具有奇数除数的节点数量
cnt_odd = [0] * n
cnt_even = [0] * n
dfs(0, 0)
ans = [cnt_odd[i] * (n - cnt_odd[i]) + cnt_even[i] * (n - cnt_even[i]) for i in range(n)]
return [x % mod for x in ans]