2016中国大学生程序设计竞赛 - 网络选拔赛
HDU 5840 This world need more Zhu
题意
- 给一棵有(N(N le 10^5))个点的树
- (M(M le 10^5))次询问,每次求(u o v)路径上第(K、2K、...、pK)个数中最大的权值(max{A_i})
思路
- 定义一个界限(B)
- 对于(K>B)的询问,用栈维护当前点到根的路径信息,每次暴力向上跳(K)步(因为对于(K le B)的用到树剖,我的做法是每次根据当前点(u)和(top[u])的距离跳)。这样的时间复杂度为(O(frac{NM}{B}))
- 对于(K le B)的询问
- 对于每个询问,拆成(u o lca)和(v o lca)两条链的询问。
- 对于(u o lca)来说,可取的点满足((dep[u]-dep[x]+1)\%K=0),即$$dep[x]%K=(dep[u]+1)%K$$
- 对于(v o lca)来说,可取的点满足((dep[u]-dep[lca]+dep[x]-dep[lca]+1)\%K=0),即$$dep[x]%K=(2dep[lca]-dep[u]-1)%K$$
- 因为是查询链上的最值,所以容易想到用树链剖分+线段树维护。
- 每次询问都是查找(dep\%K)中的最大权值,所以对于(K、dep\%K)相同的询问一块做即可。
- 时间复杂度(O(BNlogN+MlogNlogN))
代码