1|0题目链接
2|0题意简述
某公司中有 \(n\) 名员工。为方便起见,将这些员工从 1 至 \(n\) 编号。起初,员工之间相互独立。接下来,会有以下 \(m\) 次操作:
-
员工 \(y\) 成为员工 \(x\) 的上司。保证此前 \(x\) 没有上司。
-
员工 \(x\) 拿到一份文件并签字,随后交给他的上司。他的上司签字后,再交给更上一级。依此类推,直到文件传递到的那个人没有上司为止。
-
询问员工 \(x\) 是否在第 \(i\) 件文件上签过字。文件编号为上一件文件的编号再加 1,第一件文件的编号为 1。如果是,输出
YES
,否则输出NO
。
3|0解法说明
显然,我们可以将员工之间的关系看作森林,将每个员工看作一个节点,其与上司的关系看作一条边。之所以不是一棵树,是因为在 \(m\) 次操作中,有些人可能并没有被指定上司,所以员工之间的关系很可能并不是一棵树而是森林。
通过观察题面可以发现,一个员工在成为另一个员工的上司后,就不会再有更改了。由于在线操作过于麻烦,我们可以考虑离线。
具体离线方法如下:
-
对于操作 1,直接连边即可,不过这里还要在线维护一个并查集;
-
对于操作 2,分别记下第一个和最后一个对文件签字的员工,后者就是前者所在的连通块的根,利用并查集查找;
-
对于操作 3,分别记下员工编号及文件编号,离线回答。
接下来分析如何回答询问。可以发现,如果询问的员工 \(x\) 在 最开始看到文件 \(i\) 的员工与最后看到文件 \(i\) 的员工之间的链上,那么 \(x\) 就看过文件。所以,问题就被转化为了判断 \(x\) 是否在这条链上。
考虑如何判断。
设 \(st\) 为链的起始点,\(ed\) 为截止点,可推得如 \(x\) 在链上,则 \(\text{lca}(x,st) = x\) 且 \(\text{lca}(x,ed) = ed\),维护一个 LCA 即可求解。我这里用的是树剖求 LCA,倍增也可以。
还有一些细节需要注意。由于员工之间的关系是森林而非一棵树,所以我们在预处理树剖时应枚举每个点,如果该点是其所属的连通块的根,就对其进行一次预处理,且回答询问时应首先判断 \(x\) 与 \(st\)、\(ed\) 是否在同一连通块内,如果不在直接输出 NO
,否则再执行下一步操作。
剩余细节详见下面代码中的注释。
4|0通过代码
__EOF__
本文链接: https://www.cnblogs.com/Alexxtl/p/18312437.html
关于博主:I am a good person
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角 【推荐】一下。您的鼓励是博主的最大动力!