description: You should already be familiar with the concept of binary searching for a number in a sorted array. However, binary search can be extended to binary searching on the answer itself.
new Problem("Silver", "Cow Dance Show", "690", "Easy", false, [], "binary search on $K$ and simulate"),
new Problem("Silver", "Convention", "858", "Easy", false, [], "determine whether $M$ buses suffice if every cow waits at most $T$ minutes, use a greedy strategy (applies to next two problems as well)"),
new Problem("Silver", "Angry Cows", "594", "Easy", false, [], "check in $O(N)$ how many haybales you can destroy with fixed radius $R$"),
new Problem("CF", "Edu C: Magic Ship", "problemset/problem/1117/C", "Normal", false, ["Binary Search", "Prefix Sums"], "binary search on number of the days and then counting full cycles and extra days with prefix sums"),
new Problem("CF", "The Meeting Place Cannot Be Changed", "contest/782/problem/B", "Normal", false, [], "binary search on time with epsilon and then find if there exist non-empty intersection of the ranges (maximum of left points and minimum of right points)"),
new Problem("CF", "Preparing for Merge Sort", "contest/847/problem/B", "Normal", false, [], "process numbers from left to right, keep track of the last element of each block and use binary search of lower_bound to find which block the current numbers belongs"),
new Problem("CF", "Office Keys", "problemset/problem/830/A", "Normal", false, [], "notice that people will take a subarray of length n of keys. so it's possible to fix one position and binary search on another."),
new Problem("CF", "Level Generation", "problemset/problem/818/F", "Hard", false, [], "first find out which is the best way to construct the graph, then it's possible to see that the number of edges increase for some range and then decrease; so, using binary search find the last i such that f(i-1)<=f(i)"),
new Problem("CF", "Packmen", "contest/847/problem/E", "Hard", false, [], "binary search on time and check if packmen can eat all keeping left and right endpoints"),
When we binary search on the answer, we start with a search space of size $N$ which we know the answer lies in. Then, each iteration of the binary search cuts the search space in half, so the algorithm tests $O(\log N)$ values. This is efficient and much better than testing each possible value in the search space.
Let's say we have a function `check(x)` that returns `true` if the answer of $x$ is possible, and `false` otherwise. Usually, in such problems, we want to find the maximum or minimum value of $x$ such that `check(x)` is true. Similarly to how binary search on an array only works on a sorted array, binary search on the answer only works if the answer function is [monotonic](https://en.wikipedia.org/wiki/Monotonic_function), meaning that it is always non-decreasing or always non-increasing.
In particular, if we want to find the maximum `x` such that `check(x)` is true, then we can binary search if `check(x)` satisfies both of the following conditions:
- If `check(x)` is `true`, then `check(y)` is true for all $y \leq x$.
- If `check(x)` is `false`, then `check(y)` is false for all $y \geq x$.
Below, we present two algorithms for binary search. The first implementation may be more intuitive, because it's closer to the binary search most students learned, while the second implementation is shorter.
If instead we're looking for the minimum `x` that satisfies some condition, then we can binary search if `check(x)` satisfies both of the following conditions:
- If `check(x)` is true, then `check(y)` is true for all $y \geq x$.
- If `check(x)` is false, then `check(y)` is false for all $y \leq x$.
The binary search function for this is very similar. We will need to do the same thing, but when the condition is satisfied, we will cut the right part, and when it's not, the left part will be cut. Here is a more concise implementation:
```cpp
int fstTrue(function<bool(int)> f, int lo, int hi) {
hi ++; assert(lo <= hi); // assuming f is increasing
while (lo < hi) { // find first index such that f is true
int mid = (lo+hi)/2; // returns hi+1 if no index exists
f(mid) ? hi = mid : lo = mid+1;
}
return lo;
}
int main() {
ps(fstTrue([](int x) { return 1; },2,10)); // 2
ps(fstTrue([](int x) { return x >= 5; },2,10)); // 5
ps(fstTrue([](int x) { return x >= 20; },2,10)); // 11
**Statement:** Given an array $\texttt{arr}$ of $n$ integers, where $n$ is odd, we can perform the following operation on it $k$ times: take any element of the array and increase it by $1$. We want to make the median of the array as large as possible after $k$ operations.
**Solution:** We first sort the array in ascending order. Then, we binary search for the maximum possible median. We know that the number of operations required to raise the median to $x$ increases monotonically as $x$ increases, so we can use binary search. For a given median value $x$, the number of operations required to raise the median to $x$ is
If this value is less than or equal to $k$, then $x$ can be the median, so our check function returns `true`. Otherwise, $x$ cannot be the median, so our check function returns `false`.