Bajtazar 想出了一个某个排列 $(P_0, P_1, \ldots, P_{n-1})$,其中包含从 $0$ 到 $n-1$ 的数。
Bajtazar 请求你猜出在这个排列中数字 1 位于哪个位置。为了避免你完全盲猜,Bajtazar 会回答你形如:“两个不同数 $P_i$ 与 $P_j$ 的最大公约数是多少?” 的问题。
为了避免问题过于简单,你最多只能提出 $\left\lceil \frac{5n}{2} \right\rceil$ 个询问。此外,Bajtazar 会不断构造新的排列,因此你可能需要多次寻找数字 1。
交互方式
这是一个交互式任务。你需要编写一个程序,通过提供的库与 Bajtazar 进行交互。
为此,你需要通过以下指令包含头文件 gdzlib.h:
#include "gdzlib.h"
该库提供以下函数:
- int GetN() 返回参数 $n$ ($3 \le n \le 500000$) 或 $n = -1$。 若 $n \ge 3$,则表示当前所考虑排列的长度。 若 $n = -1$,表示 Bajtazar 已经没有更多排列。
- int Ask(int i, int j) 返回数 $P_i$ 与 $P_j$ 的最大公约数($0 \le i, j < n, i \ne j$)。 在一个测试用例中,该函数至多可被调用 $\left\lceil \frac{5n}{2} \right\rceil$ 次。
- void Answer(int x) 回答 $P_x = 1$ ($0 \le x < n$)。
你的程序的每次运行包含至少一个测试用例。
每个测试用例必须以 GetN() 开始,以 Answer() 结束。
当没有测试用例处于激活状态时调用 Ask() 或 Answer() 将导致“错误答案”。
处理完最后一个测试用例后,GetN() 将返回 −1。此时你应当结束程序。
同一次运行中的不同测试用例可能具有不同的 $n$。 整个运行期间所有排列长度的总和不会超过 500000。
使用任何带有不合法参数的函数调用将导致“错误答案”。 任何试图影响评测库内部行为的行为都是被禁止的。
库
与你的程序通信的库可能是“恶意的”。这意味着该库可能会根据你的提问动态调整隐藏的排列。
库的运行时间和其使用的内存可能取决于测试数据以及你的程序的具体行为。因此评测系统中的限制会比题面所给的略宽松。如果评测库运行更快或使用更少内存,那么你的程序所受的限制也会稍微减少。
程序运行示例
示例测试中只有一个测试用例。
此时 $n = 5$,隐藏排列 $P = (4, 2, 0, 3, 1)$。
| 调用的函数 | 返回值 | 说明 |
|---|---|---|
| GetN() | 5 | $n = 5$。 |
| Ask(1, 4) | 1 | $\gcd(P_1, P_4) = \gcd(2, 1) = 1$。 |
| Ask(1, 0) | 2 | $\gcd(P_1, P_0) = \gcd(2, 4) = 2$。 |
| Ask(2, 3) | 3 | $\gcd(P_2, P_3) = \gcd(0, 3) = 3$。 |
| Answer(4) | — | 我们回答 $P_4 = 1$。 |
| GetN() | −1 | 程序应当结束。 |
Bajtazar 提出了 $3$ 个 Ask() 询问,符合限制 $\left\lceil \frac{5n}{2} \right\rceil = 13$。请记住,询问次数是对每个测试用例分别计数的。
实验
示例错误解法与示例库可在 “文件” 区的压缩包中找到。 示例库的行为可能与实际评测时使用的库不同,并且可能不满足题目中的假设。 它仅用于展示交互方式。
解答程序 gdz.cpp 可按如下方式编译:
g++ -O3 -static -o gdz gdz.cpp gdzlib.cpp -std=c++17
请确保 gdzlib.h 与 gdzlib.cpp 与你的解答放在同一文件夹中。
编译完成后,库将从标准输入读取测试用例描述。
每个测试的描述包含两行:
- 第一行包含一个整数 $n$。
- 第二行包含从 $0$ 到 $n - 1$ 的一个排列。
所有测试用例结束后,最后一行应包含 −1。
示例测试对应的输入文件位于压缩包中的 gdz0.in 文件。