Loading

【题解】UOJ #33【UR #2】树上 GCD

\(\mathrm{lca}(u,v)\) 处统计 \(f(u,v)\),考虑在外面套一层莫反,那么在里面就只需要考虑枚举 \(d\),然后统计有多少个数对均为为 \(d\) 的倍数。

容易发现判断倍数可以写成:如果 \(\mathrm{dep}_u\equiv \mathrm{dep}_x\pmod{d}\) 那么 \(\mathrm{dist}(x,u)\) 就是 \(d\) 的倍数,这样就只需要以深度为下标记录每个点了。这样就可以过前三档部分分了。

第五档部分分似乎在暗示长链剖分,这样做的话信息合并的复杂度就是线性的,但是难点仍然在合并答案。考虑合并 \(a_{1,\cdots,m_1},b_{1,\cdots,m_2}\),其中 \(a_i,b_i\) 表示两个子树中 \(\mathrm{dep}=i\) 的点数,而合并的过程为:

\[t_{d}\leftarrow \left(\sum_{k=0}^{\lfloor\frac{m_1}{d}\rfloor}a_{kd+(\mathrm{dep_x}\bmod d)}\right)\left(\sum_{k=0}^{\lfloor\frac{m_2}{d}\rfloor}b_{kd+(\mathrm{dep_x}\bmod d)}\right) \]

其中 \(t_d\) 表示满足 \(d|f(u,v)\) 的数字对数 \((u,v)\) 的个数。

注意到因为合并信息的时候是将轻儿子和重儿子合并,假设 \(a_i\) 是重儿子的信息数组,\(b_i\) 是轻儿子的信息数组,那么 \(t_d\) 中关于 \(b\) 的部分直接算总复杂度为 \(O(n\log n)\),关键在于 \(t_d\) 中关于 \(a\) 的部分。

不妨考虑根号分治:

  • 对于 \(d>\sqrt{n}\) :直接算关于 \(a\) 的部分,注意到这样的 \(d\) 出现次数和轻儿子所在重链长度和有关,也就是 \(O(n)\) 的,所以总复杂度为 \(O(n\sqrt {n})\)

  • 对于 \(d\leq \sqrt{n}\) :只有 \(\sqrt{n}\)\(d\),维护一个 \(g_{d, dep_x\bmod d}\) 来表示上面关于 \(a\) 的部分,查询 \(O(1)\) 。当 \(a_{t}\rightarrow a_{t}+1\) 时,只需要枚举 \(d\) 然后在对应位置更新即可,更新次数同样和轻儿子所在重链长度和相关,也就是 \(O(n)\) 的,所以总复杂度为 \(O(n\sqrt {n})\)

代码:咕咕。

题解的做法好像不一样,到时候有空研究,不过这个做法好像更加简单些。

posted @ 2021-08-29 23:29  Qiuly  阅读(101)  评论(0编辑  收藏  举报