根号分治
原本准备讲题用的,结果讲急了没用上。
乱写的,就扔这儿吧。
先看一个题。
CF797E Array Queries
- 给定长度为
的序列 。 次询问。 - 每次询问给出
。您要不断地执行操作 ,直到 为止。询问的答案为操作次数。 , , 。
首先考虑每次询问直接做会发生什么。
如果
那预处理一些信息呢?
一次
于是
小孩子才做选择,我全都要!
不如直接选定一个分割点
最后只剩
于是喜提一个约为
根号分治
顾名思义,对于一个数据范围为
对于其中某些问题可以片面地理解为把离线算法和在线算法混合起来。
大概当注意到题目里有“两个与时间复杂度相关的元素的值的乘积不大于某个值”之类的性质,就可以往根号分治考虑了。
思想很简单,但是每个题的具体实现都不一样,比较灵活,还是有点考验思维的。值得注意的是因为复杂度带个根号,通常这种题目时限都是卡满的,建议写的时候有意识地选择常数更小的写法。
看点没那么裸的题。
Topcoder SRM589 Level-3 FlippingBits
- 给定
和一个长度为 的 01 字符串。 - 你可以进行若干次操作。
- 每次操作可以将字符串里的一个位置取反,或者是将一段长度为
的倍数的前缀全部取反。 - 问最少需要多少次操作,才能使字符串的循环节为
。 - 循环节长度为
定义为,对于任意 ,如果 这个位置存在,那么两个位置上的字符相等。 。
感觉挺
发现循环节个数和循环节长度的乘积并不超过
若
若
所以实际复杂度
不知道什么题
- 给定一个
个点 条边的无向图,初始每个点都是黑色或白色。 - 有两种操作:
- 将一个点反色。
- 查询与某个点直接连边的点中有多少个黑点。
。
首先如果出边少的话暴力维护其它点的答案显然是可以直接过的。
但是出边多咋办呢?
这时需要想到,边数固定,那么既然出边数量都到了会让你爆炸的程度,这样的点还能有多少个呢?
所以这时不如以
所以根号分治有时候分的不只是数据范围,还可以是其它抽象的东西。
CF1039D You Are Given a Tree
- 有一棵
个节点的树。 - 其中一个简单路径的集合被称为
合法当且仅当:树的每个节点至多属于其中一条路径,且每条路径恰好包含 个点。 - 对于
,求出 合法路径集合的最多路径。即:设 合法路径集合为 ,求最大的 。 。7s。
首先考虑如果
假设现在位于
如果是第一种情况的话显然取子树里那条最长的链往上连是最优的,更容易出现长度足够的路径。
考虑什么时候用第二种情况。设它的儿子所在的最长、次长链分别为
发现大概是可以证明的。设最长、次长链分别为
不咋严谨,感性理解。
于是我们获得了一个
发现
当
当
于是我们获得了一个
然而实践发现被卡常了,所以有几个小优化:
- 可以把 dfs 序和每个点的祖先预处理出来再按顺序跑,除掉递归的常数。到这里 6s。
- 每次二分的时候并不需要对整个
都找一遍。如果从小到大枚举答案的话,你已经确定了前面答案所在的区间,位于整个 的尾部,那把二分右端点放在上一个答案的前一位跑就够了。到这里 3s。 - 注意到按
分割的话两部分做法时间复杂度并不统一,理论上取 才是最优的。到这里 2s。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】