CSES - Tree Distances II

Author: Andi Qu


Time Complexity: O(n)\mathcal O(n)

It's easy to find the sum of distances from a single node - just root the tree at that node, do a DFS, and add the depths of each other node to the answer. Unfortunately, nn can go up to 21052 \cdot 10^5, so we can't just do this for each node.

If we have the answer for some node (let's say node 1), how can we quickly find the answer for its neighbours?

The key observation is that if we reroot the tree at node 1's neighbour (let's say node 2), then

  • The depths of all nodes in node 2's subtree decrease by 1.
  • The depths of all nodes outside of its subtree increase by 1.

This gives us a nice way to transition from node 1's answer to node 2's answer using only nn and the size of node 2's subtree! Observe that the change in the answer is exactly n2(node 2’s subtree size)n - 2(\text{node 2's subtree size}).

We can use DFS to find both the answer for node 1 and the size of each node's subtree when rooted at node 1, and then DFS again to compute all the answers.

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int n;
vector<int> graph[200001];
ll dp[200001], ans[200001];
void dfs1(int node = 1, int parent = 0, ll depth = 0) {
ans[1] += depth;

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!