【UR #2】树上 GCD
给定一棵树,用 ( extrm{dist}(x,y)),根节点为 (1)
对于每个 (i) 输出,求有多少对 ((u,v)) 满足 (f(u,v)=i)
其中 (x= extrm{LCA}(u,v),f(u,v)=gcd( extrm{dist}(u,x), extrm{dist}(v,x)))
(nle 2 imes 10^5)
Solution
先转换为至少,然后枚举 ( m LCA) 为 (x),对此树进行长链剖分,对于每个点分别统计贡献:
- 轻儿子的贡献。
- 轻儿子 + 重儿子的贡献。
Part 1 通过经典的容斥解决,计算至少的部分通过调和级数保证复杂度,总体复杂度为 (mathcal O(nlog n))
对于 Part2,我们设轻儿子中最长路径为 ( extrm{mx}),则显然可以被贡献的约数 (d) 不超过 ( extrm{mx}),且 (sum extrm{mx}le n)
于是可以枚举 (d) 并考虑统计答案,这里根号分治:
- 若 (dge sqrt{n}),则暴力枚举 (kd) 即 (d) 的倍数。
- 否则预处理。
其中第二部分如果在模 ({2,3,4...sqrt{n}}) 意义下考虑是难以解决的,我们不妨考虑设 (f_{x,d}) 表示 (x) 子树内所有距离 (x) 为 (d) 的倍数的点的个数,则显然我们可以枚举 (x) 的重儿子 (u) 的所有 (d) 级儿子并统计 (f_{v,d}) 的和即可。
反过来,一个 (f_{v,d}) 可以贡献至其 (d) 级祖先处(需要特判掉轻儿子的情况)
我们的瓶颈在于计算点 (x) 的 (d) 级祖先,不难注意到 (d) 为 (1sim sqrt{n}) 所以可以直接预处理。
总体复杂度 (mathcal O(nsqrt{n}))
空间复杂度乍一看是 (mathcal O(nsqrt{n})) 的,然而是可以做到 (mathcal O(n)) 的,空间开销来源于 (dle sqrt{n}) 的 Part,逐个 (d) 解决即可,空间复杂度即降低为 (O(n))
调试细节:
- 注意长链剖分的时候上界对应
<
- 添加 (d) 级祖先贡献时的条件为 (d-1) 级不为轻链顶端。
为啥我把块大小设为 (n^{frac{1}{4}}) 跑得最快啊,想不通。