CF - Sloth Naptime

Author: Sofia Yang

Table of Contents

ExplanationImplementation

Announcement With Official Editorial

Explanation

Time Complexity: O(NlogN)\mathcal{O}(N \log N)

Basically the problem statement asks if given a path from a start node to an end node on a tree, how far the sloth will travel if it has a set amount of energy, and each edge on the path has an energy cost.

We know that the sloth will always try to move upwards from the start node st\texttt{st} to the least common ancestor of the start and end nodes lca\texttt{lca}, and then move downwards from the least common ancestor towards the end node end\texttt{end}.

Let dist(i,j)\texttt{dist}(i, j) be the distance from node ii to node jj.

So if the sloth has energy amount ee, there are 3 separate cases:

  1. edist(dist(st,end)e \geq \texttt{dist}(dist(\texttt{st}, \texttt{end}). In this case the result will be the sloth reaching the end.

  2. e<dist(st, end)e < \texttt{dist(\texttt{st}, \texttt{end})} and e<dist(st, lca)e < \texttt{dist(\texttt{st}, \texttt{lca})} in which the result will be the sloth reaching the eeth parent of st\texttt{st}.

  3. e<dist(st, end)e < \texttt{dist(\texttt{st}, \texttt{end})} and edist(st, lca)e \geq \texttt{dist(\texttt{st}, \texttt{lca})} in which the result will be the sloth reaching the (edist(st, lca))(e - \texttt{dist(\texttt{st}, \texttt{lca}))}th parent of end\texttt{end}.

So first, we can can run DFS once to find the depth of every node.

Then we can create a matrix anc\texttt{anc} to store the ancestors of each node, where anc[i][j]\texttt{anc[i][j]} is the 2j2^jth ancestor of node ii.

After that, we can use binary lifting to answer each query by finding the least common ancestor of the start and end nodes, and then finding the right node that the sloth will reach.

Implementation

Java

import java.io.*;
import java.util.*;
public class SlothNaptime {
public static final int MAXN = (int)3e5 + 5;
public static final int LOGN = (int)(Math.log(MAXN) / Math.log(2)) + 1;
public static ArrayList<Integer>[] adj = new ArrayList[MAXN];
// anc[i][j] is the 2^j-th parent of i.
public static int[][] anc = new int[MAXN][LOGN];
public static int[] depth = new int[MAXN];

C++

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e5 + 5;
const int LOGN = log2(MAXN) + 1;
int depth[MAXN];
// anc[i][j] is the 2^j-th parent of i.
int anc[MAXN][LOGN];
vector<int> adj[MAXN];

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!