CF1039D You are Given a Tree 单根号做法

https://codeforces.com/topic/135071

翻译 + 一点点理解。


记答案序列为 \(ans\)

运用贪心与 DP 的思想,我们能轻易地 \(O(n)\) 求出任意单点 \(ans_i\) 的值。

现在观察 \(ans\) 序列的性质:它单调不增,且 \(0\le ans_k\le n/k\)。与其他题解不同的角度是:如果发现 \(ans_i=ans_j\),那么显然有 \(\forall i\le t\le j,ans_t=ans_i\)。于是考察一种分治做法,令 \(solve(l,r)\) 为求出 \(i\in[l,r]\)\(ans_i\) 的函数。每次若 \(ans_{l-1}=ans_{r+1}\),那么可以直接得出 \([l,r]\) 里面全部值均为 \(ans_{l-1}\);否则直接算出 \(ans_{mid}\) 的值,递归 \(solve(l,mid-1)\)\(solve(mid+1,r)\) 计算。

显然每次 \(solve(l,r)\)\(ans_{l-1},ans_{r+1}\) 的值都是已经被计算的(除了边界),所以正确性肯定没问题。

其实看代码会好理解一点!!


复杂度分析:考虑直接算出每一层递归的块数。

我们考察第 \(d\) 层,记其上一层 \(d^{\prime}=d-1\)。直接放缩复杂度,我们认为第 \(d^{\prime}\) 层全部块都被递归到了:那么显然块是均匀分布的,第 \(d^{\prime}\) 层的每一块长度都是 \(O(n/2^{d^{\prime}})\)。类似其他题解,假设第 \(d^{\prime}\) 层前 \(2^b\) 块全部都往下递归了;那么后面一段应当有 \(i\ge O(2^b\times n/2^{d^{\prime}})=O(n/2^{d^{\prime}-b})\),故后面一段 \(a_i\le O(2^{d^{\prime}-b})\)。此时看递归到第 \(d\) 层的情况,前面 \(2\times2^b\) 块,后面本质不同块只有 \(O(2^{d^{\prime}-b})\) 个,于是复杂度为

\[O(2^{b+1}+2^{d^{\prime}-b})\ge O(2\sqrt{2^{b+1}\times2^{d^{\prime}-b}})=O(2^{d/2}) \]

因此一层的递归次数只有 \(O(2^{d/2})\) 次,求和即有

\[O\left(\sum\limits_{d=0}^{\left\lceil\log n\right\rceil}2^{d/2}\right)=O\left(\dfrac{(\sqrt2)^{\left\lceil\log n\right\rceil+1}-1}{\sqrt2-1}\right)=O(\sqrt n) \]

故真正进入的层数是 \(O(\sqrt n)\) 的,每次真正进入都能够 \(O(n)\) 求出单点值,复杂度即 \(O(n\sqrt n)\)

posted @ 2025-07-13 18:30  liangbowen  阅读(13)  评论(0)    收藏  举报