Farmer John owes Bessie?NN?gallons of milk (1≤N≤10121≤N≤1012). He has to give her the milk within?KK?days. However, he doesn't want to give the milk away too quickly. On the other hand, he has to make forward progress on the loan, so he must give Bessie at least?MM?gallons of milk each day (1≤M≤10121≤M≤1012).
Here is how Farmer John decides to pay back Bessie. He first picks a positive integer?XX. He then repeats the following procedure every day:
Determine the largest?XX?such that if Farmer John follows the above procedure, Farmer John gives Bessie at least?NN?gallons of milk after?KK?days (1≤K≤10121≤K≤1012).
The only line of input contains three space-separated positive integers?NN,?KK, and?MM?satisfying?K?M<NK?M<N.
Output the largest positive integer?XX?such that Farmer John will give Bessie at least?NN?gallons using the above procedure.
10 3 3
2
For the first test case, when?X=2X=2?Farmer John gives Bessie?55?gallons on the first day and?M=3M=3?gallons on each of the next two days.
Note that the large size of integers involved in this problem may require the use of 64-bit integer data types (e.g., a "long long" in C/C++).
Problem credits: Nick Wu
[/hide]
(Analysis by Benjamin Qi)
Binary search on?XX. For the first subtask, we can check whether the number of gallons of milk that FJ gives is at least?NN?in?O(K)O(K)?time. However, this does not suffice for full points.
How can we do better than?Θ(K)?Θ(K)??As the numbers in the statement are up to?1012,1012,?not?1018,1018,?this suggests that some sort of?N??√N?factor is involved.
Suppose that we fix?X.X.?Then?YY?decreases over time. It turns out that if we process all transitions that leave?YY?unchanged in?O(1)O(1)?time, then our solution runs quickly enough! If there are more than?2N???√2N?distinct values of?YY?then FJ definitely gives Bessie enough mlik because
Thus, we can check whether?XX?works in?O(N??√)O(N)?time.
It follows that our solution runs in?O(N??√logN)O(Nlog?N)?time.
Nick Wu's code:
#include <stdio.h> int valid(long long n, long long k, long long m, long long x) { long long g = 0; while(k > 0 && g < n) { long long y = (n - g) / x; if(y < m) { long long leftover = (n-g + m-1) / m; return leftover <= k; } long long maxmatch = n - x*y; long long numdays = (maxmatch - g) / y + 1; if(numdays > k) numdays = k; g += y * numdays; k -= numdays; } return g >= n; } int main() { freopen("loan.in", "r", stdin); freopen("loan.out", "w", stdout); long long n, k, m; scanf("%lld %lld %lld", &n, &k, &m); long long lhs = 1; long long rhs = 1e12; while(lhs < rhs) { long long mid = (lhs + rhs + 1) / 2; if(valid(n, k, m, mid)) { lhs = mid; } else { rhs = mid - 1; } } printf("%lld\n", lhs); }
[/hide]
? 2025. All Rights Reserved. 沪ICP备2023009024号-1