在 JOI 有限公司的工厂里,有 $N$ 张桌子,编号为 $0$ 到 $N - 1$。工厂里有 $N - 1$ 条传送带,编号为 $0$ 到 $N - 2$。传送带 $i$ ($0 \le i \le N - 2$) 连接桌子 $A_i$ 和桌子 $B_i$。它将产品从一张桌子运送到另一张桌子。然而,我们无法直接看到传送的方向。如果我们忽略传送带的方向,任意两张桌子之间都由若干条传送带连通。
IOI-kun 是工厂的厂长。由于他忘记了每条传送带的运输方向,他将多次执行以下顺序操作:
- 他选择若干条传送带,并反转所选传送带的运输方向。
- 他选择若干张桌子,并在每张选定的桌子上放置一个产品。
- 对于每一张放置了产品的桌子,以下情况之一会同时发生:
- 如果没有传送带从该桌子运出产品,则什么都不会发生。
- 如果有传送带从该桌子运出产品,产品会通过其中一条传送带被运走。产品会停在传送带的目的地,且之后不会再移动。
- IOI-kun 确认每张桌子上是否有产品。如果某张桌子上有产品,IOI-kun 会取走所有产品。
- 对于在操作 1 中被反转方向的每条传送带,IOI-kun 会将其方向恢复。其方向变回原始方向。
IOI-kun 希望通过执行上述顺序操作至多 30 次,来确定每条传送带的原始方向。
请编写一个程序,在给定传送带连接桌子的信息后,实现 IOI-kun 的策略,通过执行上述顺序操作至多 30 次来确定每条传送带的原始方向。
实现细节
你需要提交一个文件。
该文件为 conveyor.cpp。它应该实现以下函数。程序应使用预处理指令 #include 包含 conveyor.h。
在 conveyor.cpp 中,需要实现以下函数:
void Solve(int N, std::vector<int> A, std::vector<int> B)
该函数对于每个测试用例仅被调用一次。
参数 N 是桌子的数量。
参数 A 和 B 是长度为 $N-1$ 的数组,描述了由传送带连接的桌子。
你的程序可以调用以下函数:
std::vector<int> Query(std::vector<int> x, std::vector<int> y)
使用此函数,IOI-kun 在工厂中执行操作。
参数 x 是一个长度为 $N-1$ 的数组。对于 $0 \le i \le N - 2$,如果 x[i] = 1,IOI-kun 会反转传送带 $i$ 的方向;如果 x[i] = 0,则不反转传送带 $i$ 的方向。
参数 y 是一个长度为 $N$ 的数组。对于 $0 \le j \le N - 1$,如果 y[j] = 1,IOI-kun 会在桌子 $j$ 上放置一个产品;如果 y[j] = 0,则不在桌子 $j$ 上放置产品。
令 z 为此函数的返回值。它是一个长度为 $N$ 的数组。对于 $0 \le j \le N - 1$,如果 z[j] = 1,则表示桌子 $j$ 上有一个或多个产品;如果 z[j] = 0,则表示桌子 $j$ 上没有产品。
数组 x 的长度必须等于 $N-1$。如果不满足此条件,你的程序将被判为 Wrong Answer [1]。
数组 x 的每个元素必须为 $0$ 或 $1$。如果不满足此条件,你的程序将被判为 Wrong Answer [2]。
数组 y 的长度必须等于 $N$。如果不满足此条件,你的程序将被判为 Wrong Answer [3]。
数组 y 的每个元素必须为 $0$ 或 $1$。如果不满足此条件,你的程序将被判为 Wrong Answer [4]。
Query 函数调用的次数不得超过 30 次。如果调用次数超过 30 次,你的程序将被判为 Wrong Answer [5]。
void Answer(std::vector<int> a)
使用此函数,IOI-kun 报告每条传送带的原始方向。
参数 a 是一个长度为 $N-1$ 的数组。对于 $0 \le i \le N - 2$,如果 a[i] = 0,则传送带 $i$ 将产品从 $A_i$ 运送到 $B_i$;如果 a[i] = 1,则传送带 $i$ 将产品从 $B_i$ 运送到 $A_i$。
数组 a 的长度必须等于 $N-1$。如果不满足此条件,你的程序将被判为 Wrong Answer [6]。
数组 a 的每个元素必须为 $0$ 或 $1$。如果不满足此条件,你的程序将被判为 Wrong Answer [7]。
如果 IOI-kun 报告了错误的传送带方向,你的程序将被判为 Wrong Answer [8]。
* Answer 函数应恰好被调用一次。如果 Answer 函数被调用超过一次,你的程序将被判为 Wrong Answer [9]。当 Solve 函数终止时,如果未调用 Answer 函数,你的程序将被判为 Wrong Answer [10]。
重要提示
- 你的程序可以实现其他内部函数或使用全局变量。
- 你的程序不得使用标准输入和标准输出。你的程序不得以任何方式与其他文件通信。但是,你的程序可以将调试信息输出到标准错误。
数据范围
所有输入数据满足以下条件: $0 \le A_i \le N - 1$ ($0 \le i \le N - 2$)。 $0 \le B_i \le N - 1$ ($0 \le i \le N - 2$)。 * 如果忽略传送带的方向,任意两张桌子之间都由若干条传送带连通。
子任务
- (1 分) $N = 2$。
- (14 分) $N = 30$。
- (10 分) $N = 100\,000$,$A_i = i$ ($0 \le i \le N - 2$),$B_i = i + 1$ ($0 \le i \le N - 2$)。
- (75 分) $N = 100\,000$。
样例
| 样例输入 1 | 样例函数调用 |
|---|---|
| 3 | Solve(3, [0, 2], [2, 1]) |
| 0 2 | Query([0, 0], [0, 0, 1]) $\rightarrow$ [1, 0, 0] |
| 2 1 | Query([1, 0], [1, 0, 1]) $\rightarrow$ [0, 1, 1] |
| 1 0 | Query([1, 1], [0, 0, 1]) $\rightarrow$ [0, 0, 1] |
Query([0, 1], [1, 1, 1]) $\rightarrow$ [1, 0, 1] |
|
Answer([1, 0]) |
对于第一次 Query 调用,除了 [1, 0, 0] 外,另一个可能的返回值是 [0, 1, 0]。
对于第二次 Query 调用,桌子 0 上的产品通过传送带 0 被运送到桌子 2 并停在那里。注意,该产品不会通过传送带 1 被运送到桌子 1。
注意,此样例输入不满足任何子任务的约束。