USACO Gold 2019 December - Milk Visits

Author: Benjamin Qi

Table of Contents

Method 1Method 2Method 3

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.

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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using db = double;
using str = string; // yay python!
using pi = pair<int, int>;
using pl = pair<ll, ll>;

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.

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

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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using db = double;
using str = string; // yay python!
using pi = pair<int, int>;
using pl = pair<ll, ll>;

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!