-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathfrac_bin_search.cpp
More file actions
38 lines (32 loc) · 1.11 KB
/
frac_bin_search.cpp
File metadata and controls
38 lines (32 loc) · 1.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
struct Frac {
long long a, b;
};
// Does binary search on fractions having an upper bound on
// the numerator, given a predicate pred. The predicate should
// monotonous function going from negative to 0 to positive.
// The function will find a random fraction f for which pred(f) = 0.
// Complexity: O(log(max_num))
template<typename Predicate>
Frac FracBinarySearch(long long max_num, Predicate pred) {
Frac lo{0, 1}, hi{1, 1}; // set to {1, 0} for [0...max_num)
int sign = 1;
if (pred(lo) == 0) return lo;
while (true) {
int adv = 0;
bool down = false;
for (int step = 1; step; down ? step /= 2 : step *= 2) {
adv += step;
Frac mid{lo.a * adv + hi.a, lo.b * adv + hi.b};
if (mid.a > max_num or mid.b > max_num) {
adv -= step; down = true; continue;
}
long long res = pred(mid);
if (res == 0) return mid;
if (res * sign < 0) { adv -= step; down = true; }
}
hi.a += lo.a * adv;
hi.b += lo.b * adv;
sign = -sign;
swap(lo, hi);
}
}