cojs 奈特 题解报告

才知道knight念奈特,而不念科耐特

这个题显然是一个数据结构题目,我搬运的CF上的题

CF的题解好长超长哒,而且可以在线,但是并不能看懂

于是自己想了一个一种做法A掉了,唯一的缺陷就是做法有些繁琐

首先我们把所有操作离线,之后给节点打上时间标记,从来没有被暴揍过的城市时间为m+1

之后我们考虑对于一个查询,什么样子的城市国王不会休息

显然这个城市的时间标记>=val,但是这样还不够,如果这个城市的时间标记大于当前时刻i,证明在当前查询的时候它并没有被暴揍

所以一个城市国王不会休息的充要条件是时间标记>=val且时间标记<=i

我们现在要做的事情就变成了查询u到v的链上有多少个不会被休息的城市

当然,用链上的总城市减去不会被休息的城市就是会被休息的城市数量

这在离线之后显然是可以通过一颗主席树搞定的

对于题目中要求第k个休息的城市,我们预处理倍增数组在树上倍增查询就可以啦

因为是从u走到v,所以先判断答案是-1还是在u-lca的链上还是在lca-v的的链上

细节有些繁琐,不过码码码就好啦

自己写的程序如果把每个节点的主席树定义为他的父亲到根的所有存在状态可能就会好写的多啦

不然每次查询后面都要缀一个特判QAQ

UPD:

还有另外一种做法是我们可以不建权值线段树,我们对于时间维护一颗主席树

每次查询还是利用上面的思想

这样我们为了查询第k个点就需要通过倍增或者二分变成查询链上有多少个点

我们对这棵树做树链剖分,之后我们就可以很轻松的查询链上有多少个点了

至于二分和倍增的过程可以直接放在树链剖分向上跳的过程中可以省掉一个log

时间复杂度O(nlog^2n),可以支持在线

原文地址:https://www.cnblogs.com/joyouth/p/5496830.html