省选备战报告 第零辑 分块与根号平衡

本笔记仅仅记录重点思路,详细解题过程请参阅原题题解

难度从低到高为

  • NÄIVE:有效思考时间少于十分钟
  • EASY:能够完全独立得出
  • MEDIUM EASY:需要题解提供关键思路跨越
  • MEDIUM:需要查看题解的较多思路
  • HARD:必须查看题解、并用长时间理解
  • HELL:花费极长时间理解,非常难以复现

带有加号表示实现细节较多、需要格外注意。

完全不会做的题目不包括在难度列表中

正文

T0 [SD&SXOI2022] Day1T1 整数序列

Tag

根号分治、复杂度分析、暴力

\(\sqrt{\log}\) 做法:MEDIUM(思维中等;细节中等;代码中等)

严格根号做法:MEDIUM+(思维中等;细节多;代码长)

解题要点

为何想到根号分治

每次提问中相互影响的仅有两种数据,且若规模相差悬殊,时间只取决于较小的那一个。

根号分治的特点在于,按照数量将原始数据分类。其中小块受到大小限制,大块受到个数限制。思维的关键点在于小对大的处理。

处理时利用小块数量少的特点,将此特点转化为搜索空间小的优势。

时间复杂度分析

由于大对小时间复杂度取决于小块的长度,那就尽量把最长的小块多问几次。所以当假设有 \(K\) 个大块, \(k\) 个小块时,先用最长的小块挨个问一遍大块,再用次大的、次次大的……以此类推。合起来,就是用最大的 \(\frac{q}{K}\) 个小块向每个大块各问一遍。而最强的情况下就是没有落下的小块,\(k=\frac{q}{K}\) .

接下来更进一步,每处理一个询问所需要的时间是【扫描所有 \(O(\text{小块长度})\) 个点 \(\times\)set 中查找】,总复杂度为:

\[\sum_{i=1}^{k}\sum_{j=1}^{K}l_i\log L_i \]

\(l_i\) 表示小块长度, \(L_i\) 表示大块长度

放缩,上式一定小于

\[\sum_{i=1}^{k}\sum_{j=1}^{K}l_i\log n \]

化简后可得

\[Kn\log n \]

也就是

\[O\left(\frac{n^2\log n}{B}\right) \]

不严格根号做法

小对小直接暴力,大对大也直接暴力,考虑到大块数量少,后者可以记忆化,这两部分耗时 \(O(qB + \frac{n^2}{B})\) . 小对大的情况下筛选出有效点(对于小块的每个点,分别向前向后找到一个还没有被这一过程选过的大点),然后用有效点暴力,时间复杂度上面分析过了。

因此总复杂度为 \(O(qB+\frac{n^2\log n}{B})\) ,由均值不等式可得 \(B\) 应取 \(\sqrt{\frac{n^2\log n}{q}}\) . 总复杂度为 \(O(n\sqrt{q}\cdot\sqrt{\log n})\) ,由于最后的 \(\sqrt{\log n}\) 很小,所以把 \(B\) 稍稍取小一点就足够通过本题。

严格根号做法

上一种做法中,为了筛出所有的有效点,需要采用 set 维护有效点的区间,考虑如何移除掉set

代码

T1 [ZJOI2022] Day2T2 众数

Tag

根号平衡、复杂度分析

难度:MEDIUM(思维中等;细节少;代码中等)

解题要点

为何判定为根号分治

一般有有关于“众数”、“出现次数”的题目都应想到根号分治,因为这种题目需要处理颜色个数类的信息。

如何转化问题

“加上任意数”这种条件可以直接忽略,因为这种操作可以把任意数转化为任意数。问题的本质是把区间分成两段,并在内外各选出一个数,使得这两个数的出现次数总和是所有情况中最大的。

进一步,我们发现对答案产生贡献的仅有这两个数,并且它们也一定分别是内区间与外区间的众数(若不是的话,取众数更优)。这样问题表现出了显著的根号平衡特征。

经验:根号分治适用于“两两相对”/“需要考虑出现次数”类的问题

“小对大”时间复杂度分析

在处理大对小的情况时,我们需要枚举大块 \(x\) 并在内层枚举所有小块 \(y\) 并对小块构成的纯净区间求前缀和。

纯净区间,即把颜色为 \(y\) 的所有点单独拉出来组成的区间。

其时间复杂度并非

\[O(\frac{n}{B}\times B \times n) = O(n^2) \]

而应是

\[O(\frac{n}{B} \sum len_i) = O(\frac{n^2}{B}) \]

这是因为小块的个数不能按照 \(O(n)\) 处理。

小对小处理

大对小的情况下处理外层枚举大块前缀和即可,小对小的情况下,考虑到小块最多的元素个数也只有 \(\sqrt{n}\) 级别,并且计算贡献的时候我们完全不需要知道两数的具体取值。所以,枚举内区间众数的出现次数 \(K\) 即可。这一层的时间复杂度为 \(\sqrt{n}\) .

内循环需要枚举所有的众数出现次数为 \(K\) 的区间,并计算出此时外区间众数的出现次数。

T2 [CF1039D] You are given a tree

Tag

贪心及其证明、根号平衡、二分

难度:MEDIUM EASY(思维中等;细节少;代码短)

解题要点

为什么贪心是对的

本题的 \([1,\sqrt{n}]\) 部分需要用到朴素的贪心处理 \(\sqrt{n}\) 遍,每次解决 “在一棵树上最多能画几条长度为 \(k\) 的不相交链” 这样一个问题。

而这个问题可以 \(O(n)\) 贪心解决,具体来说,每个点记录“空余链长”,也就是从它开始向下数最长的还未被占用的链长。

对于每一个点,判断它儿子中【空余链长最长、次长的两个】能否放下一条长度为 \(k\) 的链。如果能,就把这个点的空余链长记录为 \(0\) ;如果不能,空余链长记录为儿子中空余链长最长的再加一。边界条件为【叶节点的空余链长为 \(1\) 】。

为什么是对的呢?考虑决策包容性。假设存在一个点 \(x\) ,它的两个儿子既可以支持一条通过 \(x\) 而不向上延伸的链,但最优解中 \(x\) 被一条连向父亲的链通过(没有利用上儿子的孔空余链长),那么我们可以把这条链放下来,充分利用儿子提供给它的空间。

同时,如果只看 \(x\) 的上方,最优解中的排布方式还能实现,并且还能获得额外的排布方式;如果只看 \(x\) 的下方,排布方式根本没有变化。这样,我们证明了 “把链尽量放下来” 完全包容了最优解。进一步也就证明了贪心的正确性。

为何考虑到根号平衡

考虑数值不同的答案的分布情况,发现后半部分出现大量答案重叠,猜测以根号为分界线。

后半部分的做法

这一部分有点类似于数论分块。

我们发现最后的 \(n-\sqrt{n}\) 个位置分了 \(\sqrt{n}\) 个答案数值,那么一定会有重复的。如何确定重复的区域呢?可以使用二分,首先枚举答案 \(k\) ,然后对于每个 \(k\) 二分查找此时最长的链长度,check 函数可以利用刚刚的贪心实现。

为什么是二分?因为答案随链长的增加单调不增,具体来说,如果能放下 \(t\) 条长度为 \(k\) 的链,那么没有理由放不下同样 \(t\) 条长度更短的。

把两个部分合起来,时间复杂度为 \(O(nB + \frac{n^2\log n}{B})\) 因此可以把块长改为 \(\sqrt{n\log n}\) .

笛卡尔树科技

posted @ 2023-02-28 20:34  HMSF  阅读(28)  评论(0编辑  收藏  举报