浅谈根号算法

前言

本人在 HL 集训时爱上了根号算法,遂开此坑。

所有根号算法都有一个共性:与暴力算法息息相关。但它们并不是拙劣的暴力,而是优美的暴力。所以根号算法也被称之为“暴力美学”。

根号分治就是一个典型的根号算法。当题目性质与 xnx 都有关时,我们可以找到一个分界点 B=n 进行分治,一部分直接暴力,另一种部分利用上述性质使用某种方式来处理,这样我们就达到了一种微妙的平衡。

通过上面的例子,我们知道了大部分根号算法的另一个特点:在两个信息之间寻找平衡。分块思想也是如此。它将区间 [1,n] 分为若干个长度为 n 的块,每次区间操作(或询问)时,没有完全覆盖一个块的“边角料”可以暴力,而完全覆盖它的部分可以直接对整个块进行打标记等操作。前者虽然理论复杂度是 O(n),但是需要暴力的“边角料”只有 O(n) 个点,所以它的实际复杂度是 O(n)。后者虽然理论复杂度较低(一般为 O(ploylogn),为了方便,这里看做 O(1)),但是它需要对 O(n) 个块进行操作,所以它的实际复杂度也是 O(n)。可以看到,分块在块长和块的数量中找到了平衡,它也将单次操作复杂度维持在了 O(n)

莫队是一种特殊的根号算法,它将操作(或询问)离线,由上次的结果进行暴力修改移动,得到了这次的结果。这种算法还将操作(或询问)按照某种方式排序,使得每次暴力修改移动的次数不超过 O(n)(有的是 O(n32)),进而保障了复杂度。

当然,根号算法也可以和其他算法(比如二分)结合,这样会使得复杂度在根号内或外带若干支 log

总体来说,根号算法避免了使用递归数据结构,使得程序常数较小。当然,根号的复杂度不够优秀并且较难优化,这也是它最大的问题。所以,熟练掌握根号算法并不是你放弃学习其他数据结构的理由。

(其实还有整除分块,但是它属于数学内容,所以就不放在这里啦。)

1. 分块

分块并不是一种算法,而是一种思想,这里主要讲解与数据结构有关的分块算法。

分块:从入门(绿题)到黑题。目前进度:蓝题?

1.1 思想介绍

(这里先咕咕咕,因为我在这里不方便画图)

1.2 入门九题

hzwer 的分块题,是分块入门的好题。

数列分块入门 1

区间修改,单点查询。

区间修改时,边角(没有完全覆盖一个块的部分)在原数组上暴力修改,完全覆盖的在块上打标记,单点查询答案为原数组的值 + 它在所在块的标记值。

代码。

数列分块入门 2

区间修改,查询区间内排名。

其实是查询区间内小于 x 的数的个数。

我们对于每个块,维护它内部元素升序,这样我们可以二分查找块内小于 x 的数量。还是将区间修改分成两部分:

  • 边角暴力。边角部分暴力修改元素,但需要维护块内有序,修改后还需要给块内排序。
  • 块内打标记。注意到区间加不改变顺序,所以可以直接打标记。

块内二分我手写一直不对,最后还是换成 STL 的二分了,至今不知道为什么。

代码。

数列分块入门 3

区间修改,查询区间内前驱。

跟上面一样,随便做就行。

代码。

数列分块入门 4

区间修改,区间求和。

打标记 + 维护块内权值和即可。

代码。

数列分块入门 5

区间开方,区间求和。

首先,01 开方之后都是它本身,也就是说,如果一个块内只有 01,那么我们就不用操作,否则就暴力遍历开方,因为开方不会有太多次,所以这样暴力复杂度是能过的。

代码。

posted @   Eliauk_FP  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示