Official Analysis (Offline)

To solve this problem online, we need efficiently find the closest ancestor of a farm xx with a certain milk type. Here are several ways to do this.

Method 1

Run the same DFS mentioned in the analysis. For each milk type, store the Euler tour indices at which the answer changes. Then we can get the answer for a vertex using a single lower_bound operation on the vector for the corresponding milk type.

Implementation

Time Complexity: O(logN)\mathcal{O}(\log N) per query.

C++

#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
const int MX = 200005;
int T[MX];
template <int SZ> struct LCA {
static const int BITS = 32 - __builtin_clz(SZ);

Method 2

Generate a persistent array for each vertex where the indices of the array correspond to the milk types.

Time Complexity: O(logN)\mathcal{O}(\log N) per query. Apparently this is doable in O(loglogN)\mathcal{O}(\log \log N) per query (paper). Is this bound optimal for this problem?

Method 3

Use HLD. We can check whether there exists a farm in the path from a vertex xx to the root of the heavy path containing xx (root[x]\texttt{root}[x]) with the desired milk type in O(1)\mathcal{O}(1) time using an unordered map. Note that we only need to do two upper_bound operations per query.

In the solution below, I refer to milk types as "colors."

Implementation

Time Complexity: O(logN)\mathcal{O}(\log N) per query.

C++

#include <algorithm>
#include <iostream>
#include <map>
#include <unordered_map>
#include <vector>
/**
* Description: Heavy-Light Decomposition, add val to verts
* and query sum in path/subtree.
* Time: any tree path is split into $\mathcal{O}(\log N)$ parts

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!