有一条长度为 $l$ 米的街道从左向右延伸,有 $n$ 个小型路由器占据了沿途不同的位置。原点定义为街道的最左端。路由器从左到右编号为 $0$ 到 $n-1$,路由器 $i$ 放置在距离原点 $p[i]$ 米的位置。
保证路由器 $0$ 位于原点,且每个路由器到原点的距离(以米为单位)均为偶数。
你希望找出所有 $n$ 个路由器的位置。由于路由器非常小,从远处难以辨认,你决定使用以下过程来寻找它们: 将探测器放置在距离原点 $x$ 米的位置。 使用探测器找出距离它最近的路由器的编号。如果有两个路由器到它的距离相等,它将返回编号较小的那个路由器。
你最多可以使用探测器 $q$ 次。请设计一种策略来找出所有路由器的位置。
实现细节
你需要实现以下过程:
int[] find_routers(int l, int n, int q)
- $l$:街道的长度(单位:米)。
- $n$:路由器的数量。
- $q$:探测器最多可使用的次数。
- 该过程将被评测程序调用恰好一次。
- 它应该返回一个数组 $p$,表示每个路由器的位置,其中 $p[i]$ 是路由器 $i$ 到原点的距离。
上述过程可以调用以下过程:
int use_detector(int x)
- $x$:探测器与原点之间的距离。
- $x$ 必须至少为 $0$ 且至多为 $l$。
- 该过程将返回距离探测器最近的路由器的编号。如果有两个路由器到它的距离相等,它将返回编号较小的那个。
- 该过程调用次数不得超过 $q$ 次。
样例
样例 1
考虑以下调用:
find_routers(5, 2, 10)
街道长度为 $5$ 米,有 $2$ 个路由器,允许最多调用 $10$ 次 use_detector。假设路由器分别位于距离原点 $0$ 和 $4$ 米处。
find_routers 过程可以选择调用 use_detector(3),返回 $1$,因为位于位置 $4$ 的路由器 $1$ 距离探测器最近。
随后 find_routers 过程可以选择调用 use_detector(2),返回 $0$,因为路由器 $0$ 和 $1$ 距离探测器相等,且路由器 $0$ 的编号较小。
此时,已有足够的信息得出路由器分别位于位置 $0$ 和 $4$。
因此,find_routers 过程应返回 [0, 4]。
样例 2
考虑以下调用:
find_routers(6, 3, 10)
街道长度为 $6$ 米,有 $3$ 个路由器,允许最多调用 $10$ 次 use_detector。假设路由器分别位于距离原点 $0$、$2$ 和 $6$ 米处。
find_routers 过程可以选择调用 use_detector(5),返回 $2$,因为路由器 $2$ 位于位置 $6$,距离探测器最近。
随后 find_routers 过程可以选择调用 use_detector(4),返回 $1$,因为路由器 $1$ 和 $2$ 到探测器的距离相等。
此时,已有足够的信息得出路由器分别位于位置 $0$、$2$ 和 $6$。
因此,find_routers 过程应返回 [0, 2, 6]。
数据范围
- $p[0] = 0$
- $0 \le p[i] \le l$ 且 $p[i]$ 为偶数。(对于所有 $0 \le i \le n-1$)
- $p[i] < p[i+1]$(对于所有 $0 \le i \le n-2$)
- $5 \le l \le 100\,000$
子任务
- (16 分) $l = 100\,000, n = 2, q = 100\,001$
- (21 分) $l = 100\,000, n = 100, q = 100\,001$
- (23 分) $l = 100\,000, n = 2, q = 20$
- (40 分) $l = 100\,000, n = 1000, q = 20\,000$
此外,子任务 4 是一个部分分任务。设 $m$ 为所有测试用例中调用 use_detector 的最大次数。
- 如果 $m > 20\,000$,得 $0$ 分。
- 如果 $7500 < m \le 20\,000$,你将获得 $\frac{20\,000 - m}{12\,500} \cdot 40$ 分。
- 如果 $m \le 7500$,你将获得 $40$ 分。
样例评测程序
样例评测程序按以下格式读取输入:
- 第 1 行:$l \ n \ q$
- 第 2 行:$p[0] \ p[1] \ \dots \ p[n-1]$
样例评测程序按以下格式打印你的答案:
- 第 1 行:由
find_routers返回的 $p[0] \ p[1] \ \dots \ p[n-1]$。 - 第 2 行:调用
use_detector的次数。