uoj#P664. 【IOI2021】dungeons
【IOI2021】dungeons
由于某些原因本题仅支持 C++, C++11 语言的提交。
Robert 正在设计一款新的电脑游戏。游戏中有一位英雄、$n$ 个敌人和 $n + 1$ 个地牢。敌人从 $0$ 到 $n - 1$ 编号,地牢从 $0$ 到 $n$ 编号。敌人 $i$($0 \le i \le n - 1$)处在地牢 $i$,其能力值为 $s[i]$。地牢 $n$ 里没有敌人。
英雄一开始进入地牢 $x$,初始能力值为 $z$。每次英雄进入地牢 $i$($0 \le i \le n - 1$)时,都需要面对敌人 $i$,且会发生以下情况中的一种:
如果英雄的能力值大于等于敌人 $i$ 的能力值 $s[i]$,那么英雄会胜出。这使得英雄的能力值增加 $s[i]$($s[i] \ge 1$)。这种情况下,下一步英雄将会进入地牢 $w[i]$($w[i] > i$)。
否则英雄会战败,这使得英雄的能力值增加 $p[i]$($p[i] \ge 1$)。在这种情况下,下一步英雄将会进入地牢 $l[i]$。
注意 $p[i]$ 可能会小于、等于、大于 $s[i]$,$l[i]$ 可能会小于、等于、大于 $i$。无论对战结果如何,敌人 $i$ 始终处在地牢 $i$,且能力值为 $s[i]$。
当英雄进入地牢 $n$ 的时候,游戏结束。可以看出无论英雄的起始地牢和初始能力值如何,游戏一定会在有限次对战之后结束。
Robert 希望你通过 $q$ 次模拟来对游戏进行测试。对于每次模拟,Robert 输入英雄的起始地牢 $x$ 和初始能力值 $z$。你需要做的是对于每次模拟给出游戏结束时英雄的能力值。
实现细节
你必须引用 keys.h
头文件。
你要实现以下函数:
void init(int n, int[] s, int[] p, int[] w, int[] l)
- $n$:敌人的数量。
- $s$、 $p$、 $w$、 $l$:长度为 $n$ 的序列。对于每一个 $i$($0 \le i \le n - 1$):
- $s[i]$ 是敌人 $i$ 的能力值,也是击败敌人 $i$ 后英雄增加的能力值。
- $p[i]$ 是英雄被敌人 $i$ 击败后增加的能力值。
- $w[i]$ 是英雄击败敌人 $i$ 后进入的下一个地牢的编号。
- $l[i]$ 是英雄被敌人 $i$ 击败后进入的下一个地牢的编号。
- 恰好调用此函数一次,且发生在任何对如下的
simulate
函数的调用之前。
int64 simulate(int x, int z)
- $x$:英雄的起始地牢编号。
- $z$:英雄的初始能力值。
- 假设英雄的起始地牢编号为 $x$,初始能力值为 $z$,函数的返回值是相应情况下游戏结束时英雄的能力值。
- 恰好调用此函数 $q$ 次。
输入格式
评测程序示例以如下格式读取输入数据:
- 第 $1$ 行:$n \; q$
- 第 $2$ 行:$s[0] \; s[1] \; \ldots \; s[n − 1]$
- 第 $3$ 行:$p[0] \; p[1] \; \ldots \; p[n − 1]$
- 第 $4$ 行:$w[0] \; w[1] \; \ldots \; w[n − 1]$
- 第 $5$ 行:$l[0] \; l[1] \; \ldots \; l[n − 1]$
- 第 $6 + i$ 行($0 \le i \le q - 1$):$x \; z$,是第 $i$ 次调用
simulate
的参数。
输出格式
评测程序示例以如下格式打印你的答案:
- 第 $1 + i$ 行($0 \le i \le q - 1$):第 $i$ 次调用
simulate
的返回值。
3 2
2 6 9
3 1 2
2 2 3
1 0 1
0 1
2 3
24
25
考虑以下调用:
init(3, [2, 6, 9], [3, 1, 2], [2, 2, 3], [1, 0, 1])
上图对应这次的 init
调用。每一个正方形都代表了一个地牢。对于所有存在敌人的地牢,$s[i]$、$p[i]$ 对应的值都已经在正方形内表示出来了。红色箭头展示了英雄战胜敌人后游戏状态的变化,黑色箭头展示了英雄战败后游戏状态的变化。
这时如果调用 simulate(0, 1)
,游戏会以如下方式进行:
地牢编号 | 英雄在战斗前的能力值 | 胜负结果 |
---|---|---|
$0$ | $1$ | 战败 |
$1$ | $4$ | 战败 |
$0$ | $5$ | 胜出 |
$2$ | $7$ | 战败 |
$1$ | $9$ | 胜出 |
$2$ | $15$ | 胜出 |
$3$ | $24$ | 游戏结束 |
因此,simulate(0, 1)
的返回值应该是 $24$。
这时如果调用 simulate(2, 3)
,游戏会以如下方式进行:
地牢编号 | 英雄在战斗前的能力值 | 胜负结果 |
---|---|---|
$2$ | $3$ | 战败 |
$1$ | $5$ | 战败 |
$0$ | $6$ | 胜出 |
$2$ | $8$ | 战败 |
$1$ | $10$ | 胜出 |
$2$ | $16$ | 胜出 |
$3$ | $25$ | 游戏结束 |
因此,simulate(2, 3)
的返回值应该是 $25$。
数据范围
对于所有数据:
- $1 \le n \le 400 \, 000$
- $1 \le q \le 50 \, 000$
- $1 \le s[i], p[i] \le {10}^7$(对于所有的 $0 \le i \le n - 1$)
- $0 \le l[i], w[i] \le n$(对于所有的 $0 \le i \le n - 1$)
- $w[i] > i$(对于所有的 $0 \le i \le n - 1$)
- $0 \le x \le n - 1$
- $1 \le z \le {10}^7$
子任务 | 分值 | 特殊限制 |
---|---|---|
$1$ | $11$ | $n \le 50 \, 000$,$q \le 100$,$s[i], p[i] \le 10 \, 000$(对于所有的 $0 \le i \le n - 1$) |
$2$ | $26$ | $s[i] = p[i]$(对于所有的 $0 \le i \le n - 1$) |
$3$ | $13$ | $n \le 50 \, 000$,所有的敌人拥有相同的能力值,即 $s[i] = s[j]$,对于所有的 $0 \le i, j \le n - 1$ |
$4$ | $12$ | $n \le 50 \, 000$,所有的 $s[i]$ 至多有 $5$ 种不同的数值 |
$5$ | $27$ | $n \le 50 \, 000$ |
$6$ | $11$ | 没有额外的约束条件 |
时间限制:$\texttt{4s}$
空间限制:$\texttt{2GB}$