CF1744E1 题解

· · 题解

notice:本题解重点在于讲解如何使用查找算法通过此题,而非重点讲解数学内容。

坑点

暴力

大体思路

双重循环,使用 flag 标记是否找到,找到后直接输出,跳出循环即可。

**核心代码** ```cpp bool flag = false; for (int i = a + 1; i <= c; i ++) { // notice: long long if (flag) break; for (int j = b + 1; j <= d; j ++) { if (i * j % (a * b) == 0) { cout << i << ' ' << j << '\n'; flag = true; break; } } } if (!flag) cout << "-1 -1\n"; ``` 实测 TLE on #9。 ## 二分 **大体思路** 二分的简单优化在于只使用一个循环遍历每个 $x$,然后再二分 $y$,最后输出即可。 这里实际上需要简单推式子: 对于每个 $x$,$\because ab \mid xy \quad \therefore \frac {ab} {\gcd {x, ab}} \mid y$。看出这一点后,在 $10 ^ 5$ 范围内用二分查找有无符合 $b < y \le d$ 的数即可。 这个环节也可以通过其他查找方法解决,这里不再一一赘述。 **核心代码** ```cpp for (int i = a + 1; i <= c; i ++) { int w = a * b / __gcd(a * b, i); int l = 1, r = 1e5, mid; while (l <= r) { mid = (l + r) / 2; if (b < mid * w && d >= mid * w) { flag = true; break; } else if (mid * w <= b) l = mid + 1; else r = mid - 1; } if (flag) { cout << i << ' ' << mid * w << '\n'; break; } } if (!flag) cout << "-1 -1\n"; ``` 实测 AC。