科学委员会正在中欧信息学奥林匹克竞赛(CEOI)的开幕式上放松心情。任务已经准备就绪,评分服务器的 $10^{12}$ 道防火墙也已全部开启,委员会正期待着一场精彩的火炬表演。一切都不会出错。除了……没人买足够的油来点燃那些火炬!现在,委员会需要帮助来维持表演,同时不耗尽他们的燃油储备。
在表演过程中,会有表演者排成一列,从左到右编号,起始编号为 1。表演者的数量会随时间变化。每位表演者手持一支火炬,在任何时间点,火炬可能处于点燃状态,也可能处于熄灭状态。最初,只有一名表演者的火炬是点燃的。
表演分为 $Q$ 个动作。在动作 $a$ 开始时,要么有 $p_a > 0$ 名表演者决定加入队列右侧,要么有最右侧的 $p_a > 0$ 名表演者决定离开。这超出了委员会的控制范围。最左侧的表演者始终留在舞台上。新加入的表演者的火炬未点燃,离开的表演者如果火炬处于点燃状态,则会将其熄灭。
一旦动作 $a$ 的表演者队列准备就绪,委员会必须宣布一个数字 $t_a \ge 0$。随后,每位火炬处于点燃状态的表演者会将其火焰分享给右侧的 $t_a$ 名表演者。这意味着,表演者 $i$ 的火炬在动作结束后处于点燃状态,当且仅当在动作开始前,表演者 $\max\{i - t_a, 1\}, \dots, i$ 中至少有一人的火炬是点燃的。为了使表演更具动态性,$t_a$ 不能大于 $5p_a$,且应尽可能小(详见下文评分部分)。
在每个动作结束时,委员会必须告知每一位当前火炬处于点燃状态的表演者是否将其熄灭。出于美观考虑,最右侧表演者的火炬在动作结束后应始终处于点燃状态。此外,为了节约燃油,处于点燃状态的火炬数量不得超过 150 个。
请编写一个程序,告诉委员会如何在这些约束条件下进行表演。
交互
这是一个交互式任务。你必须实现以下三个函数:
void prepare():在开始时被调用。你可以使用此函数进行设置(或什么都不做)。pair<long long, vector<long long>> join(long long p_a):当有 $p_a > 0$ 名表演者加入队列右侧时被调用。此函数必须返回一个二元组,包含委员会宣布的数字 $t_a$ 以及动作结束后火炬应处于点燃状态的表演者列表。该列表必须严格递增。pair<long long, vector<long long>> leave(long long p_a):当最右侧的 $p_a > 0$ 名表演者离开队列时被调用。同样,它必须返回一个二元组,包含委员会宣布的数字 $t_a$ 以及动作结束后火炬应处于点燃状态的表演者列表,且列表必须严格递增。
如果你的任何返回值不满足上述约束,你的程序将立即终止,并被判为“不正确”(Not correct)。你不得向标准输出写入内容或从标准输入读取内容;否则,你可能会收到“安全违规”(Security violation!)的判决。但你可以自由地向标准错误流(stderr)写入内容。
你必须在源代码中包含 light.h 文件。为了在本地测试你的程序,你可以将其与 sample_grader.cpp 链接,该文件可在任务附件中找到。有关示例评测器的说明,请参阅 sample_grader.cpp。附件中还包含一个示例实现 light_sample.cpp。
数据范围
令 $N$ 表示在任何时间点同时站在队列中的最大表演者人数。在所有测试用例中,$N \le 10^{17}$ 且 $1 \le Q \le 50\,000$。
- 子任务 1(5 分):每个测试用例中只有一次
leave调用。 - 子任务 2(5 分):$N \le 700$
- 子任务 3(10 分):$N \le 5\,000$
- 子任务 4(5 分):$N \le 25\,000$
- 子任务 5(10 分):$N \le 100\,000$
- 子任务 6(5 分):$N \le 500\,000$
- 子任务 7(60 分):无其他约束。
部分评分:在子任务 7 中,你的实际得分取决于所有动作中 $t_a / p_a$ 的最大值,具体如下表所示:
| $\max t_a / p_a$ | $[0, 1]$ | $(1, 2]$ | $(2, 3]$ | $(3, 5]$ |
|---|---|---|---|---|
| 得分 | 60 | 35 | 20 | 10 |
特别地,要获得满分,join 和 leave 的所有返回值必须满足 $t_a \le p_a$。
样例
考虑一个 $Q = 4$ 的测试用例。你的程序与评测器之间的交互可能如下所示:
| 调用 | 返回值 | 说明 |
|---|---|---|
prepare() |
— | 你可以在此处进行任何设置(或什么都不做) |
| 表演开始,有一名表演者的火炬是点燃的 | ||
join(3) |
3, {2, 4} |
三名表演者加入,总共四名表演者;表演者 1 点燃了表演者 2、3 和 4 的火炬;随后,表演者 1 和 3 熄灭了他们的火炬 |
leave(2) |
0, {2} |
最右侧的两名表演者离开(仅剩两名);没有新的火炬被点燃;表演者 2 的火炬保持点燃 |
join(2) |
3, {2, 4} |
两名新表演者加入(总共四名);表演者 2 点燃了表演者 3 和 4 的火炬;表演者 3 随后熄灭了他们的火炬 |
join(3) |
3, {2, 4, 7} |
三名新表演者加入(总共七名);首先表演者 3、5、6 和 7 的火炬被点燃,然后表演者 3、5 和 6 再次熄灭了他们的火炬 |
上述交互过程在公共测试用例中由 light_sample.cpp 复现。请注意,上述 join 和 leave 的调用序列在任何子任务中都构成一个有效的测试用例。