2016中国大学生程序设计竞赛

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)的询问
    1. 对于每个询问,拆成(u o lca)(v o lca)两条链的询问。
    2. 对于(u o lca)来说,可取的点满足((dep[u]-dep[x]+1)\%K=0),即$$dep[x]%K=(dep[u]+1)%K$$
    3. 对于(v o lca)来说,可取的点满足((dep[u]-dep[lca]+dep[x]-dep[lca]+1)\%K=0),即$$dep[x]%K=(2dep[lca]-dep[u]-1)%K$$
    4. 因为是查询链上的最值,所以容易想到用树链剖分+线段树维护。
    5. 每次询问都是查找(dep\%K)中的最大权值,所以对于(K、dep\%K)相同的询问一块做即可。
    6. 时间复杂度(O(BNlogN+MlogNlogN))

代码

原文地址:https://www.cnblogs.com/mcginn/p/5835936.html