[BZOJ4381][POI2015]Odwiedziny (树链刨分/倍增)

该博客讨论了BZOJ4381题目,涉及树形结构和边长为1的点权重。文章探讨了当询问步数c大于等于根号N时,如何通过模拟和倍增算法在sqrt(N)logN的时间复杂度内解决问题。对于c小于根号N的情况,使用DP预处理并结合LCA(最近公共祖先)实现。尽管倍增方法效率较低且代码复杂,但作者指出树链剖分在处理爬树问题时具有更好的常数因子,适合处理特定的数据构造。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给定一棵树,边长为1,点带权。处理M个询问,格式为u,v,c,求从u走到v每次跳c步经过的点权之和,最后一步若不足c条边则直接走到v。N,M<=5w。

分成c>=sqrt(N)和c<sqrt(N)两种情况处理。若c>=sqrt(N),则显然步数不超过根号N步,然后模拟即可,如果是用的倍增的话一次询问就是sqrt(N)logN。不过claris上课讲了一个根号就能回答的方法,但是我忘啦。。对所有c<sqrt(N)的用简单的DP全部预处理出来,用lca的复杂度就可以回答询问了。但是这题越过lca的部分等等边界条件的处理非常恶心。。

但是倍增确实太慢了,并且代码一大坨,空间开销也大。其实爬树也可以用树链刨分的。把DFS序搞出来,然后不断向上找,直到要找的点与当前点在一条重链时他们的DFS序就一定是连续的,就可以回答了。链剖的常数比倍增小到哪儿去了。。考虑当数据构造等问题,阀值设得比sqrt(N)小会更快。。

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<assert.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define erp(i,a,b) for(int i=a;i>=b;--i)
c
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值