Table of Contents

ExplanationImplementation

Official Analysis (C++)

Explanation

Firstly, notice that we can binary search on the answer, or XX in this case. For each XX, we must check if it is valid, and update the binary search accordingly. We can binary search on XX because, for smaller values of XX, we are giving more gallons of milk. Therefore, if it is possible for one XX value to meet the requirement, it is possible for all of the values less than that XX to do so as well.

To efficiently determine whether a given XX value is valid, we can simulate the process. However, we process all states where YY, the number of gallons Bessie pays back, does not change all at once.

Additionally, notice that if Bessie gives more than 2N\sqrt{2N} distinct values of YY, then she will have definitely paid off the debt, since 1+2++2NN1 + 2 + \ldots + \sqrt{2N} \ge N, which means that the upper bound of the number of operations we must make is 2N\sqrt{2N}, satisfying our time constraints.

Therefore, we can validate a given value of XX in O(N)\mathcal{O} (\sqrt{N}) time, and the entire solution runs in O(NlogN)\mathcal{O}(\sqrt{N}\cdot \log {N}).

Implementation

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

C++

#include <algorithm>
#include <fstream>
#include <iostream>
using std::cout;
using std::endl;
/**
* @return whether Farmer John gives Bessie at least N (numGallons)
* gallons of milk within withinDays with the given X value

Java

import java.io.*;
import java.util.*;
public class Loan {
/**
* @return whether Farmer John gives Bessie at least N (numGallons)
* gallons of milk within withinDays with the given X value
*/
static boolean canRepay(long numGallons, long withinDays, long atLeast, long xVal) {
long g = 0;

Python

def can_repay(num_gallons: int, within_days: int, at_least: int, x_val: int) -> bool:
"""
:return: whether Farmer John gives Bessie at least N (num_gallons)
gallons of milk within within_days with the given X value
"""
g = 0
while within_days > 0 and g < num_gallons:
y = (num_gallons - g) // x_val
if y < at_least:
leftover = (num_gallons - g + at_least - 1) // at_least

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!