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(NlogN) 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]
© 2024. All Rights Reserved. 沪ICP备2023009024号-1