【题解】Solution Set - NOIP2024集训Day12 树上启发式合并

【题解】Solution Set - NOIP2024集训Day12 树上启发式合并

https://www.becoder.com.cn/contest/5472


「CF600E」Lomsat gelral

直接 dsu on tree。记录每一个颜色的出现次数。


「IOI2011」Race

之前是用点分治做的。

考虑 dsu on tree。每个子树内维护到根节点的距离为 \(x\) 的最短条数(就是最小深度。

然后加入轻儿子的时候更新当前答案就行了。


因为我们优先计算轻儿子的答案,所以在清空当前子树的影响的时候,可以直接全部清除。


「CF375D」Tree and Queries

比较暴力的两只 \(\log\) 的 dsu on tree 做法,是再用一个线段树维护每个 \(cnt\) 有多少个。

线段树合并的做法,就是再用一个线段树维护 \(cnt\),这样就做到了单 \(\log\)


现在再来仔细想一想单 \(\log\) 的 dsu on tree 的做法。

考虑到每次 \(cnt\) 最多只会 \(\pm 1\),我们就可以 \(O(1)\) 维护大于等于 \(k\) 的个数有多少个。


「CF715C」Digit Tree

一眼推式子题。(下面的运算都在模 \(m\) 的意义下进行。

\[\sum_{i=1}^{len} w_i\times 10^i\equiv 0\pmod m \]

还是 不太好做。😅


考虑维护每个点到根节点组成的所构成的数字 \(f_i\),根节点到每个点组成的所构成的数字 \(g_i\)

(根节点的 \(dep\)\(0\)

\[\text{lca}(u,v)=d\\ Ans(u,v)=(f_u-f_d)\times 10^{-dep_d}\times 10^{dep_v-dep_d}+(g_v-g_d\times 10^{dep_v-dep_d}) \]

对于加入的点作为开头,查询点作为结尾(加入左边,查询右边。

\[f_u =-(g_v-g_d\times 10^{dep_v-dep_d})\times 10^{2dep_d-dep_v} + f_d\\ f_u=g_d\times 10^{dep_d}-g_v\times 10^{2dep_d-dep_v}+f_d \]

对于加入的点作为结尾,查询点作为开头(加入左边,查询右边。

\[g_v\times 10^{-dep_v}=-(f_u-f_d)\times 10^{-2dep_d}+g_d\times 10^{-dep_d}\\ g_v\times 10^{-dep_v}=(g_d\times 10^{-dep_d})-(f_u-f_d)\times 10^{-2dep_d} \]


其实感觉一般的 dsu on tree。

难点就在于选好在 ds(一般是桶)里面维护什么,以及查询什么。并且能够满足全局的性质(不能因为根节点的改变而改变的量,比如到当前子树的根的距离)

跟当前子树的根有关的变量都放在查询那边。


「UOJ284」快乐游戏鸡

先把 \(s-t\) 这条链拿出来,求出 \(w\) 的最大值 \(mx\)

显然每次回到原点之后是一个很类似的过程,我们往下的策略相当于是 bfs。每一层的答案就是 \(w\) 的最大值。

所以我们要维护的是每一个深度最大的 \(w\),每一层的贡献就是 \(\max(mx-w_{i-1},0)\)

posted @ 2024-08-21 20:27  CloudWings  阅读(9)  评论(0编辑  收藏  举报