首页 >> 资讯

CF983E NN country 题解

2023-08-17 02:10:14来源:哔哩哔哩

题意

给定一棵树和若干条路线,每条路线相当于  之间的路径,途径路径上的每个点。

给出若干个询问,每次询问从  到  至少需要利用几条路线。


【资料图】

Solution

考虑子问题,两个询问点在同一条链上,这样问题就类似 [SCOI2015] 国旗计划,只不过这道题是环上问题,但思路相同。

对于链,考虑贪心,对于每一个点  跳到能到达的最远的点 ,容易想到下一步应当是跳到 ,故考虑倍增优化这个不断往前跳的过程。定义  为点 i 跳  步能到达的最远节点,可以用  复杂度的时间来处理出  数组。

考虑树上的两个点,对于  是  的祖先节点( 为  祖先节点时同理)的情况,同链上情况处理。

对于两个点分别不是对方父亲节点的情况,考虑将问题拆分为  到  和  到  两个问题处理。令 为  跳到  的最小步数, 为  跳到  的最小步数, 为  向上跳  步到达的深度最浅的节点,即跳到  的前一个节点, 同理。考虑两种情况:

有一条路线同时经过  和 ;

不存在一条路线同时经过  和 。

对于第二种情况,答案即为 ,对于第一种情况,答案为 。问题转化为如何维护是否存在一条路线经过两个点。

发现对于一个节点 ,只要 的子树中存在一个点,使得存在一条从其出发的路径在 的子树中结束,则存在一条路径同时经过 和 。考虑通过 dfs 序转化为区间问题,令  为节点  的子树大小,则问题进一步转化为询问是否存在一条路径  使得 。考虑二维数点,即查询平面上矩形  是否有点。将询问离线排序并用树状数组维护即可。

有个小细节:由于  和  在此题中是等价的,故在插入点时都应插入,否则可能会统计不到这个点。

其他具体实现细节见代码,以及由于我不会倍增求 lca,所以写了个树剖。

总时间复杂度应该是  的,但是有巨大常数,可以通过本题。

code

关键词:

相关新闻