#L3527. 「IOI2021」地牢游戏

「IOI2021」地牢游戏

题目描述

注意:请在提交源代码前添加 #include "dungeons.h"

Robert 正在设计一款新的电脑游戏。游戏中有一位英雄、nn 个敌人和 n+1n + 1 个地牢。敌人从 00n1n - 1 编号,地牢从 00nn 编号。敌人 ii0in10 \le i \le n - 1)处在地牢 ii,其能力值为 s[i]s[i]。地牢 nn 里没有敌人。

英雄一开始进入地牢 xx,初始能力值为 zz。每次英雄进入地牢 ii0in10 \le i \le n - 1)时,都需要面对敌人 ii,且会发生以下情况中的一种:

  1. 如果英雄的能力值大于等于敌人 ii 的能力值 s[i]s[i],那么英雄会胜出。这使得英雄的能力值增加 s[i]s[i]s[i]1s[i] \ge 1)。这种情况下,下一步英雄将会进入地牢 w[i]w[i]w[i]>iw[i] > i)。

  2. 否则英雄会战败,这使得英雄的能力值增加 p[i]p[i]p[i]1p[i] \ge 1)。在这种情况下,下一步英雄将会进入地牢 l[i]l[i]

注意 p[i]p[i] 可能会小于、等于、大于 s[i]s[i]l[i]l[i] 可能会小于、等于、大于 ii。无论对战结果如何,敌人 ii 始终处在地牢 ii,且能力值为 s[i]s[i]

当英雄进入地牢 nn 的时候,游戏结束。可以看出无论英雄的起始地牢和初始能力值如何,游戏一定会在有限次对战之后结束。

Robert 希望你通过 qq 次模拟来对游戏进行测试。对于每次模拟,Robert 输入英雄的起始地牢 xx 和初始能力值 zz。你需要做的是对于每次模拟给出游戏结束时英雄的能力值。


实现细节

你要实现以下函数:

void init(int n, int[] s, int[] p, int[] w, int[] l)
  • nn:敌人的数量。
  • ss, pp, ww, ll:长度为 nn 的序列。对于每一个 ii0in10 \le i \le n - 1):
    • s[i]s[i] 是敌人 ii 的能力值,也是击败敌人 ii 后英雄增加的能力值。
    • p[i]p[i] 是英雄被敌人 ii 击败后增加的能力值。
    • w[i]w[i] 是英雄击败敌人 ii 后进入的下一个地牢的编号。
    • l[i]l[i] 是英雄被敌人 ii 击败后进入的下一个地牢的编号。
  • 恰好调用此函数一次,且发生在任何对如下的 simulate 函数的调用之前。
int64 simulate(int x, int z)
  • xx:英雄的起始地牢编号。
  • zz:英雄的初始能力值。
  • 假设英雄的起始地牢编号为 xx,初始能力值为 zz,函数的返回值是相应情况下游戏结束时英雄的能力值。
  • 恰好调用此函数 qq 次。

评测程序示例

评测程序示例以如下格式读取输入数据:

  • 11 行:n  qn \; q
  • 22 行:s[0]  s[1]    s[n1]s[0] \; s[1] \; \ldots \; s[n − 1]
  • 33 行:p[0]  p[1]    p[n1]p[0] \; p[1] \; \ldots \; p[n − 1]
  • 44 行:w[0]  w[1]    w[n1]w[0] \; w[1] \; \ldots \; w[n − 1]
  • 55 行:l[0]  l[1]    l[n1]l[0] \; l[1] \; \ldots \; l[n − 1]
  • 6+i6 + i 行(0iq10 \le i \le q - 1):x  zx \; z,是第 ii 次调用 simulate 的参数。

评测程序示例以如下格式打印你的答案:

  • 1+i1 + i 行(0iq10 \le i \le q - 1):第 ii 次调用 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]s[i]p[i]p[i] 对应的值都已经在正方形内表示出来了。红色箭头展示了英雄战胜敌人后游戏状态的变化,黑色箭头展示了英雄战败后游戏状态的变化。

这时如果调用 simulate(0, 1),游戏会以如下方式进行:

地牢编号 英雄在战斗前的能力值 胜负结果
0 1 战败
1 4
0 5 胜出
2 7 战败
1 9 胜出
2 15
3 24 游戏结束

因此,simulate(0, 1) 的返回值应该是 2424

这时如果调用 simulate(2, 3),游戏会以如下方式进行:

地牢编号 英雄在战斗前的能力值 胜负结果
2 3 战败
1 5
0 6 胜出
2 8 战败
1 10 胜出
2 16
3 25 游戏结束

因此,simulate(2, 3) 的返回值应该是 2525


数据范围与提示

对于所有数据:

  • 1n4000001 \le n \le 400 \, 000
  • 1q500001 \le q \le 50 \, 000
  • 1s[i],p[i]1071 \le s[i], p[i] \le {10}^7(对于所有的 0in10 \le i \le n - 1
  • 0l[i],w[i]n0 \le l[i], w[i] \le n(对于所有的 0in10 \le i \le n - 1
  • w[i]>iw[i] > i(对于所有的 0in10 \le i \le n - 1
  • 0xn10 \le x \le n - 1
  • 1z1071 \le z \le {10}^7

子任务

子任务 分值 特殊限制
1 11 n50000n \le 50 \, 000q100q \le 100s[i],p[i]10000s[i], p[i] \le 10 \, 000(对于所有的 0in10 \le i \le n - 1
2 26 s[i]=p[i]s[i] = p[i](对于所有的 0in10 \le i \le n - 1
3 13 n50000n \le 50 \, 000,所有的敌人拥有相同的能力值,即 s[i]=s[j]s[i] = s[j],对于所有的 0i,jn10 \le i, j \le n - 1
4 12 n50000n \le 50 \, 000,所有的 s[i]s[i] 至多有 55 种不同的数值
5 27 n50000n \le 50 \, 000
6 11 没有额外的约束条件