Fish eating fruit
测试地址 题意简述: 树上任意两点之间的路径按照模 3 为 012 分类,将两点间距离加和,乘 2 即为答案。 解题思路: 可以采用树上dp解决,也可以点分治,这里先给出一种树上dp做法: dp[i][k] 表示距 i 模 3 为 k 的节点距离和。 tc[i][k] 表示距 i 模 3 为 k 的节点数目。 ans[k] 表示所有路径中模 3 为 k 的路径的总长度。 目标答案是 ans[k] 。 初始状态 tc[i][0] = 1 。 如果每次只考虑所有经过根 x 的路径,并且路径上的一个端点在x的一个子树上,另一个端点在另一个子树上(其他所有情况都可以在x的祖先或者子节点被考虑到,所以这样可以包含所有情况)。 假设当前枚举到x的子节点y,之前遍历的子节点已经使得dp和tc数组更新完成,那么我们要计算的路径起点在y,终点在之前遍历过的所有子节点中。 分类讨论答案贡献: 边 x-y 对答案的贡献:设 j,k属于{0,1,2},x 到 y 的边权为 z ,那么z对答案的贡献为 tc[x][j] * tc[y][k] * z 。 终点是 y 的所有路径长度的贡献: dp[y][k] * tc[x][j] * z 。 起点是 x 的所有路径长度的贡献: dp[x][j] * tc[y][k] * z 。 于是状态转移方程: dp[x][(j+z)%3] += dp[y][j] + z