P10220 [省选联考 2024] 迷宫守卫 题解
Last_Flame · · 题解
题目传送门
思路
考虑对于一棵子树,如果我们确定了探险者 Bob 第一个取到的符文,那么接下来他必须按从深到浅的顺序进入与路径相连的节点为。那么我们考虑贪心,对于一棵子树,找到探险者 Bob 能取到的符文中最小编号最大是多少。
考虑什么情况下一个符文不能第一个取到,当且仅当唤醒了该符文的一个祖先
考虑对于整棵树,我们如何确定 Bob 第一个取到的符文。我们按编号从小到大枚举符文,对于每个符文,我们先看它是否处在某个已被唤醒的守卫的右子树内,如果是,那么考虑下一个符文,否则我们找到他的祖先中
那么我们就知道了 Bob 第一个选择的符文了,然后我们考虑模拟 Bob 的行动,每次进入到一颗新的子树就重复上述操作。
然后你写出来了,然后你交了,然后你只得了
考虑这样做有哪些花费是有损耗的。考虑我们在某子树中让一些守卫守住了一些符文(让这些符文不能被第一个选到),但这些符文在更大的子树内,也都被另一些守卫守住了,那么这个时候只需要保留深度深的守卫守住这些符文即可,更大子树中的那些守卫是被浪费了的。
所以我们考虑在递归到某个子树时,如果这个子树的根是其父节点的右儿子,且其父节点守卫已被唤醒,那么尝试将这个守卫守住的符文分给子树内多个守卫守住,如果可以,那么就敲晕这个守卫,再递归到子树内。考虑这么做的正确性,由于是字典序,所以按 Bob 行动的顺序操作,在递归前尝试拆守卫,显然正确。
考虑时间复杂度,每个符文可能在以它的任一祖先为根的子树内被尝试加入,一次加入是
code
我们需要知道某子树中,比某个符文大的最小符文,考场写的是主席树,其实可以使用类似归并排序的方法,记录每个符文在每个子树内的
把守卫敲晕,可以使用类似线段树懒标记的操作。
主席树实现(这个是暴力敲晕守卫,复杂度错误但是能过)
归并实现