AT_joisc2017_e 壊れた機器 (Broken Device)
Description
[problemUrl]: https://atcoder.jp/contests/joisc2017/tasks/joisc2017_e
Anna 和 Bruno 是赌术大师。他们将和担任庄家的 D-taro 玩一个游戏。在这个游戏中,Anna 和 Bruno 分别待在不同的房间里。他们只能使用一台损坏的装置相互通信。D-taro 会给 Anna 一个整数。对于 Anna 和 Bruno 来说,这个游戏的目标是使用该装置,把给定的整数从 Anna 传递给 Bruno。
当游戏开始时,一开始,Anna 声明一个整数 $m$,其取值在 1 到 2 000(含)之间。然后他们进行 $Q$ 轮。第 $i$ 轮($1 \le i \le Q$)按如下方式进行。
1. D-taro 给 Anna 一个整数 $A_i$。
2. Anna 向装置输入数组 $s_i, t_i$。数组 $s_i, t_i$ 的每个元素都必须为 0 或 1。数组 $s_i, t_i$ 的长度必须相同,且长度在 1 到 $m$(含)之间。
3. 令 $u_i$ 为由数组 $s_i$ 和 $t_i$ 通过 **riffle shuffle**(见下文)得到的数组。然后装置将 $u_i$ 发送给 Bruno。
4. Bruno 向 D-taro 发送一个整数。若该整数与 D-taro 给 Anna 的整数 $A_i$ 相同,则 Anna 和 Bruno 在本轮获胜。
请编写实现 Anna 和 Bruno 策略的程序,使他们在全部 $Q$ 轮中都能获胜。
### 洗牌交错(riffle shuffle)
若能将数组 $Z$ 的元素划分为两组,并满足以下两个条件,则称数组 $Z$ 是由数组 $X$ 和数组 $Y$ 通过 riffle shuffle 得到的。
* 由第一组元素按原有顺序组成的数组等于数组 $X$。
* 由第二组元素按原有顺序组成的数组等于数组 $Y$。
例如,数组 $Z = [1, 1, 1, 0, 0, 0]$ 可由 $X = [1, 1, 0]$ 与 $Y = [1, 0, 0]$ 通过 riffle shuffle 得到,因为由 $Z$ 的第 1、2、4 个元素按原顺序组成的数组为 $[1, 1, 0]$,而由第 3、5、6 个元素按原顺序组成的数组为 $[1, 0, 0]$。
另一方面,若 $X = [1, 1, 0]$、$Y = [1, 0, 0]$,而 $Z = [0, 0, 0, 1, 1, 1]$,则数组 $Z$ 不是由 $X$ 和 $Y$ 通过 riffle shuffle 得到的。
### 实现细节
你需要提交两个文件。
第一个文件是 `Anna.cpp`。它应实现 Anna 的策略,并实现下列函数。程序应通过预处理指令 `#include` 包含 `Anna.h`。
* `int Declare()`
该函数在开始时被调用一次。
* 返回值是 Anna 声明的整数 $m$。
* 整数 $m$ 必须在 1 到 2 000(含)之间。若不满足此条件,你的程序将被判为 **Wrong Answer [1]**。
* `std::pair 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$(含)之间。若不满足此条件,你的程序将被判为 **Wrong Answer [3]**。
* 数组 $s_i, t_i$ 的长度必须相同。若不满足此条件,你的程序将被判为 **Wrong Answer [4]**。
第二个文件是 `Bruno.cpp`。它应实现 Bruno 的策略,并实现下列函数。程序应通过预处理指令 `#include` 包含 `Bruno.h`。
* `long long Bruno(std::vector 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` 的可执行文件。
请注意,实际评测器与样例评测器不同。样例评测器以单进程形式运行,从标准输入读入数据,并将结果写到标准输出。
Input Format
样例评测器从标准输入读取如下数据。
> $Q$ \
> $A_1$ \
> $A_2$ \
> $\vdots$ \
> $A_Q$
Output Format
样例评测器向标准输出写出如下信息(引号仅为说明)。
* 若你的程序被判定为正确,它会输出函数 `Declare` 的返回值 $m$,例如 “Accepted: 2000”。
* 若你的程序被判定为任一类 Wrong Answer,样例评测器会写出其类型,例如 “Wrong Answer [1]”。
如果你的程序同时触犯多类 Wrong Answer 的条件,样例评测器只报告其中一种。
样例评测器在每一轮计算 riffle shuffle 时使用伪随机数。其结果在不同执行中不会改变。为了更改伪随机数的种子,请如下方式执行样例评测器。
```
./grader 2022
```
第一个参数应为一个整数。
Explanation/Hint
#### 约束
* $1 \le Q \le 1\,000$。
* $1 \le A_i \le 1\,000\,000\,000\,000\,000\,000 \ (= 10^{18}) \ (1 \le i \le Q)$。
#### 子任务
1. (5 分)$A_i \le 2\,000 \ (1 \le i \le Q)$。
2. (5 分)$A_i \le 4\,000\,000 \ (1 \le i \le Q)$。
3. (3 分)$A_i \le 10\,000\,000 \ (= 10^7) \ (1 \le i \le Q)$。
4. (12 分)$A_i \le 100\,000\,000 \ (= 10^8) \ (1 \le i \le Q)$。
5. (15 分)$A_i \le 100\,000\,000\,000 \ (= 10^{11}) \ (1 \le i \le Q)$。
6. (60 分)无限制。对于本子任务,你的得分计算如下。
* 令 $m^*$ 为本子任务所有测试中,Anna 声明的整数 $m$ 的最大值。
* 你的得分如下所示。
| $m^*$ 的取值 | 分数 |
| :--- | :--- |
| $201 \le m^* \le 2\,000$ | $40 - 25 \times \log_{10}\!\left(\dfrac{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
```
| 调用 | 返回值 |
| :--- | :--- |
| `Declare()` | 4 |
| `Anna(42)` | `([0, 0, 1, 0], [1, 1, 0, 1])` |
| `Bruno([1, 0, 0, 1, 0, 1, 0, 1])` | 42 |
| `Anna(2000)` | `([0, 1], [0, 0])` |
| `Bruno([0, 0, 1, 0])` | 2000 |
在该样例输入中,共有 $Q \ (= 2)$ 轮。对于第 1 轮,D-taro 给 Anna 的整数为 $A_1 \ (= 42)$。
对于第 2 轮,D-taro 给 Anna 的整数为 $A_2 \ (= 2000)$。
该样例输入满足所有子任务的约束。