Anna 和 Bruno 是博弈大师。他们将与游戏的庄家 D-taro 进行一场游戏。
在这个游戏中,Anna 和 Bruno 待在不同的房间里。他们只能通过一个损坏的设备进行交流。D-taro 会给 Anna 一个整数。对于 Anna 和 Bruno 来说,这个游戏的目标是通过该设备将给定的整数从 Anna 传给 Bruno。
游戏开始时,Anna 首先声明一个 $1$ 到 $2000$ 之间的整数 $m$(包含 $1$ 和 $2000$)。然后进行 $Q$ 轮游戏。第 $i$ 轮($1 \le i \le Q$)的操作如下:
- D-taro 给 Anna 一个整数 $A_i$。
- Anna 向设备输入数组 $s_i, t_i$。数组 $s_i, t_i$ 的每个元素都应为 $0$ 或 $1$。数组 $s_i, t_i$ 的长度应相同,且长度在 $1$ 到 $m$ 之间(包含 $1$ 和 $m$)。
- 令 $u_i$ 为由数组 $s_i$ 和 $t_i$ 通过洗牌(riffle shuffle,见下文)得到的数组。设备将 $u_i$ 发送给 Bruno。
- Bruno 向 D-taro 发送一个整数。如果该整数与 D-taro 给 Anna 的整数 $A_i$ 相同,则 Anna 和 Bruno 在本轮获胜。
请编写程序实现 Anna 和 Bruno 的策略,使得他们在所有 $Q$ 轮中都能获胜。
洗牌 (Riffle Shuffle)
如果我们可以将数组 $Z$ 的元素分成两组,使得满足以下两个条件,则称数组 $Z$ 是由数组 $X$ 和 $Y$ 通过洗牌得到的:
- 由第一组元素按原顺序组成的数组等于数组 $X$。
- 由第二组元素按原顺序组成的数组等于数组 $Y$。
例如,数组 $Z = [1, 1, 1, 0, 0, 0]$ 是由 $X = [1, 1, 0]$ 和 $Y = [1, 0, 0]$ 通过洗牌得到的,因为由 $Z$ 的第 $1, 2, 4$ 个元素按原顺序组成的数组是 $[1, 1, 0]$,由 $Z$ 的第 $3, 5, 6$ 个元素按原顺序组成的数组是 $[1, 0, 0]$。
另一方面,如果 $X = [1, 1, 0]$,$Y = [1, 0, 0]$,且 $Z = [0, 0, 0, 1, 1, 1]$,则数组 $Z$ 不能由 $X$ 和 $Y$ 通过洗牌得到。
实现细节
你需要提交两个文件。
第一个文件是 Anna.cpp。它应该实现 Anna 的策略。它应该实现以下函数。程序应使用预处理指令 #include 包含 Anna.h。
int Declare()该函数在开始时调用一次。- 返回值是 Anna 声明的整数 $m$。
- 整数 $m$ 应在 $1$ 到 $2000$ 之间(包含 $1$ 和 $2000$)。如果不满足此条件,你的程序将被判为 Wrong Answer [1]。
std::pair<std::vector<int>, std::vector<int> > Anna(long long A)在调用Declare函数后,该函数会被调用 $Q$ 次。第 $i$ 次调用($1 \le i \le Q$)对应第 $i$ 轮的第 $1$ 步和第 $2$ 步。- 参数 $A$ 是 D-taro 给 Anna 的整数 $A_i$。
- 返回值是 Anna 输入到设备中的两个数组 $s_i, t_i$ 的配对。
- 数组 $s_i, t_i$ 的每个元素都应为 $0$ 或 $1$。如果不满足此条件,你的程序将被判为 Wrong Answer [2]。
- 数组 $s_i, t_i$ 的长度都应在 $1$ 到 $m$ 之间(包含 $1$ 和 $m$)。如果不满足此条件,你的程序将被判为 Wrong Answer [3]。
- 数组 $s_i, t_i$ 的长度应相同。如果不满足此条件,你的程序将被判为 Wrong Answer [4]。
第二个文件是 Bruno.cpp。它应该实现 Bruno 的策略。它应该实现以下函数。程序应使用预处理指令 #include 包含 Bruno.h。
long long Bruno(std::vector<int> u)在 Anna 向设备输入数组后,该函数会被调用一次。总共调用 $Q$ 次。第 $i$ 次调用($1 \le i \le Q$)对应第 $i$ 轮的第 $3$ 步和第 $4$ 步。- 参数 $u$ 是设备在第 $i$ 轮发送给 Bruno 的数组 $u_i$。
- 返回值是 Bruno 发送给 D-taro 的整数。
- 返回值应与 D-taro 给 Anna 的整数 $A_i$ 相同。如果不满足此条件,你的程序将被判为 Wrong Answer [5]。
重要说明
- 你的程序可以实现其他内部函数或使用全局变量。提交的文件将与评测程序一起编译,并成为一个可执行文件。所有全局变量和内部函数都应在匿名命名空间中声明,以避免与其他文件冲突。评测时,它将作为 Anna 和 Bruno 两个进程执行。Anna 的进程和 Bruno 的进程不能共享全局变量。
- 你的程序不得使用标准输入和标准输出。你的程序不得通过任何方式与其他文件通信。但是,你的程序可以将调试信息输出到标准错误。
编译与运行
你可以从比赛网页下载包含样例评测程序的压缩包来测试你的程序。压缩包中还包含你的程序的样例源文件。
样例评测程序是 grader.cpp。为了测试你的程序,请将 grader.cpp、Anna.cpp、Bruno.cpp、Anna.h、Bruno.h 放在同一个目录下,并运行以下命令来编译你的程序:
g++ -std=gnu++17 -O2 -o grader grader.cpp Anna.cpp Bruno.cpp
编译成功后,将生成可执行文件 grader。
注意,实际的评测程序与样例评测程序不同。样例评测程序将作为一个单一进程执行,它会从标准输入读取输入数据并将结果写入标准输出。
数据范围
- $1 \le Q \le 1000$。
- $1 \le A_i \le 1\,000\,000\,000\,000\,000\,000 \, (= 10^{18}) \quad (1 \le i \le Q)$。
子任务
- (5 分) $A_i \le 2000 \quad (1 \le i \le Q)$。
- (5 分) $A_i \le 4\,000\,000 \quad (1 \le i \le Q)$。
- (3 分) $A_i \le 10\,000\,000 \, (= 10^7) \quad (1 \le i \le Q)$。
- (12 分) $A_i \le 100\,000\,000 \, (= 10^8) \quad (1 \le i \le Q)$。
- (15 分) $A_i \le 100\,000\,000\,000 \, (= 10^{11}) \quad (1 \le i \le Q)$。
- (60 分) 无附加限制。对于此子任务,你的得分计算如下:
- 令 $m^*$ 为 Anna 在此子任务的所有测试用例中声明的整数 $m$ 的最大值。
- 你的得分如下:
| $m^*$ 的值 | 得分 |
|---|---|
| $201 \le m^* \le 2000$ | $40 - 25 \times \log_{10} \left( \frac{m^*}{200} \right)$ 分(向下取整) |
| $161 \le m^* \le 200$ | $40$ 分 |
| $156 \le m^* \le 160$ | $44$ 分 |
| $151 \le m^* \le 155$ | $48$ 分 |
| $146 \le m^* \le 150$ | $52$ 分 |
| $141 \le m^* \le 145$ | $56$ 分 |
| $m^* \le 140$ | $60$ 分 |
样例
输入格式 1
2 42 2000
输出格式 1
Accepted: 2000
说明
在此样例输入中,共有 $Q (= 2)$ 轮。对于第 $1$ 轮,D-taro 给 Anna 整数 $A_1 (= 42)$。对于第 $2$ 轮,D-taro 给 Anna 整数 $A_2 (= 2000)$。 此样例输入满足所有子任务的限制。