#L4155. 「JOISC 2024 Day3」JOI 之旅
「JOISC 2024 Day3」JOI 之旅
题目描述
题目译自 JOISC 2024 Day3 T2「JOI ツアー / JOI Tour」
在 IOI 国有 个城市,编号为 到 ,有 条道路,编号为 到 。路 双向连接城市 和城市 。可以通过道路从一个城市到达其他任意城市。
IOI 国的每个城市都有一家餐厅。在城市 的餐厅类型用 表示:
:果汁店
:日式煎蛋卷店
:冰淇淋店
理惠女士正在规划一个叫做 JOI 之旅的观光计划。JOI 之旅按如下顺序前往 3 种餐厅:
选择有果汁店的城市 ,并从城市 开始旅行。
前往城市 的果汁店。
选择有日式煎蛋卷店的城市 ,并从城市 出发乘公交车沿最短路径前往城市 。
前往城市 的日式煎蛋卷店。
选择有冰淇淋店的城市 ,并从城市 出发乘公交车沿最短路径前往城市 。
前往城市 的冰淇淋店。
在城市 结束行程。
为了避免游客无聊,理惠女士决定选择三个城市 满足它们不会经过相同的道路两次。称这样的 JOI 之旅是好的。
需要计算好的 JOI 之旅的数量。即满足以下条件的三元组 的个数:
城市 中的餐厅是果汁店。
城市 中的餐厅是日式煎蛋卷店。
城市 中的餐厅是冰淇淋店。
当沿最短路径从城市 移动到 再移动到 的过程中,不会经过相同的道路两次。
在 IOI 国,会有 次餐厅类型改变的事件。当第 个事件发生时,会给出两个整数 和 ,满足 且 。然后,在城市 的餐厅类型会变为 。即当 时,餐厅类型会分别变为果汁店、日式煎蛋卷店和冰淇淋店。
在每个事件过后,需要立即计算最新的好的 JOI 之旅的数量。
实现细节
需要在程序开头引入库 joitour.h。
需要实现如下函数:
void init(int N, std::vector F, std::vector U, std::vector V, int Q) 使用此函数给出道路和餐厅信息。 这个函数仅在程序开始时调用一次。
参数 是城市个数 。
参数 是长为 的数组。 表示城市 中餐厅的类别,即 。
参数 和 是长为 的数组。 和 是被路 连接的两个城市 和 。
参数 是餐厅类型改变事件的个数 。
void change(int X, int Y) 使用此函数给出餐厅类型改变事件。 这个函数被调用 次。
第 次调用中,参数 是餐厅类型改变发生的城市编号,即 。
第 次调用中,参数 是餐厅的新类型,即 。保证新类型与原类型不同。
long long num_tours() 这个函数在以下场景被调用,共 次:
在执行完函数 init 后。
在执行完函数 change 后。
这个函数应返回最新的好 JOI 之旅数。
重要提示
程序可以实现其它函数供内部使用,或者使用全局变量。
程序禁止使用标准输入输出。程序禁止与其他文件通过任何方式交互。但程序可以使用标准错误输出输出调试信息。
编译和测试运行
你可以在「文件 - 附加文件」中下载样例交互器来测试你的程序。附加文件中还包含一个样例程序。
样例交互器是文件 grader.cpp。为了测试你的程序,请将 grader.cpp、joitour.cpp 和 joitour.h 放在同一目录下,并且执行如下命令编译程序。此外你也可以运行 compile.sh 来编译你的程序。
g++ -std=gnu++20 -O2 -o grader grader.cpp joitour.cpp
当编译成功时,会生成可执行文件 grader。
注意测评时使用的交互器与样例交互器不同。样例交互器会以单进程的形式执行,它会从标准输入中读入数据,输出结果到标准输出。
样例交互器输入格式
第一行一个整数 。
第二行 个整数 。
接下来 行,每行两个整数 。
接下来一行一个整数 。
接下来 行,每行两个整数 。
样例交互器输出
样例交互器会在每次调用 num_tours 函数后输出一行一个整数,表示这个函数的返回值。
样例1:
3
0 1 2
0 1
1 2
0
1
| init(3, [0, 1, 2], [0, 1], [1, 2], 0) | |
| num_tours() |
只有一个好的 JOI 之旅,表示为 。下面是对于它满足是好的 JOI 之旅条件的解释:
,在城市 0 的餐厅是果汁店。
,在城市 1 的餐厅是日式煎蛋卷店。
,在城市 2 的餐厅是冰淇淋店。
当我们沿最短路径从城市 0 移动到 1,然后从 1 移动到 2 时,我们没有经过相同的道路两次。
因此,第一次 num_tours() 函数的调用返回值为 1。
这组样例满足子任务 1, 2, 3, 4, 6, 7 的限制。
样例2:
3
0 1 2
0 1
1 2
2
2 0
0 2
1
0
1
| 函数调用 | 返回值 |
|---|---|
| init(3, [0, 1, 2], [0, 1], [1, 2], 2) | - |
| num_tours() | |
| change(2, 0) | - |
| num_tours() | |
| change(0, 2) | - |
| num_tours() |
最初有一个好的 JOI 之旅,表示为 。因此,第一次 num_tours() 函数的调用返回值为 1。
在第一个事件中,在城市 2 的餐厅从冰淇淋店变成了果汁店。在这次变化后,冰淇淋店从 IOI 国消失了,好的 JOI 之旅也没有了。因此,第二次 num_tours() 函数的调用返回值为 0。
在第二个事件中,在城市 0 的餐厅从果汁店变成了冰淇淋店。在这次变化后,有一个好的 JOI 之旅,表示为 。因此,第三次 num_tours() 函数的调用返回值为 1。
这组样例满足子任务 1, 2, 4, 6, 7 的限制。
样例3:
7
1 0 2 2 0 1 0
0 1
0 2
1 3
1 4
2 5
2 6
7
0 0
1 1
2 0
3 0
4 2
5 2
6 2
3
0
4
4
0
4
5
5
这组样例满足子任务 1, 2, 5, 6, 7 的限制。
数据规模与提示
可以通过道路从一个城市前往任意其他城市
对于每次调用函数 change,新类型不同于原类型
| 无附加限制 |