专栏文章
根号分治和莫队
个人记录参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miptv4d1
- 此快照首次捕获于
- 2025/12/03 17:51 3 个月前
- 此快照最后确认于
- 2025/12/03 17:51 3 个月前
根号分治与莫队
根号分治是一种奇怪的分块
-
根号分治算法是一种用于优化数据结构和算法复杂度的技术。
-
对于题目中的某两个约束,它们总是相互制约的,并且这种制约是“乘积”关系——步长和项数,总有一个不能太大。
-
针对这两个情况分别设计算法,然后将两种算法结合起来,就能获得一个完整的解决问题的算法。
-
大多数数据结构都擅长处理“连续区间”的询问,而不擅长间隔区间之间的询问。
-
令区间间隔为 ,对于 的情况预存部分和 ,对于 的情况暴力扫描,就可以保证算法时间复杂度为
莫队
- 莫涛发明的,解决区间查询的离线算法,基于根号分治,复杂度为 。
- 一般来说,如果可以在 内从 的答案转移到 这四个与之紧邻的区间的答案,则可以考虑使用莫队。
莫队思想
-
分块+排序,通过合理排序查询顺序,减少区间指针移动次数。
-
精髓在于排序,以确保时间复杂度
-
普通莫队是基于分块的离线算法,用于解决区间查询。
-
使用范围
- 只询问不修改
- 允许离线
- 在已知的情况下能得到的答案。
-
若满足掉件,就可以在的复杂度内求出所有询问的姐(前提是n与m同阶,理解为n = m)。
莫队实现
- 将所有询问读入进来后进行离线操作
- 将这些询问排序,否则就是TMD暴力
- 顺序处理这些询问,暴力的从上一个区间答案转移到下一个区间答案,即左右指针一步步移动。
排序
- 现将n个数的序列分块,分成 个块
- 然后,将询问的左端点按块从小到大排序
- 相同的再按右端点排序
- 优化:奇偶性排序,就是让奇数块和偶数块的排序相反。例如,左端点都在奇数块,则对从大到小排序,若在偶数块,则对从小到大排序(反之亦可)。
why?
奇偶性排序用于减少指针移动的总次数,从而降低时间复杂度
莫队基本思想是将数组分块,按左端点所在块排序,同块内按右端点升序排序,这样左指针在块间移动时,右端点尽可能单调递增,减少来回移动
但同一块内的查询若全部按右端点升序排序,可能会出现以下问题:
- 左指针在块内从左到右移动时,右端点先递增到块末尾,下一个查询的左指针跳回块开头时,右端点可能需要跳回左边,导致右端点反复横跳,增加移动次数
奇偶性排序的优化逻辑
规则是:
- 奇数块内的查询,按右端点升序排序
- 偶数块内的查询, 按右端点降序排序
关键优化在于
- 块间切换时,右端点移动方向交替: 如处理完奇数块(右端点升序到最大)后,切换到下一个偶数块时,右端点会从当前最大值跳转到偶数块的右端点(降序起点),随后逐步向左移动,避免了右端点先右移再左移的麻烦。
复杂度
单独考虑左端点:复杂度为
单独考虑右端点,复杂度为
综上,时间复杂度为,因为同阶,所以是。
不同阶时
复杂度为
步骤
块大小 block =
维护变量:
- cnt[x]:x在当前区间的出现次数
- ans:当前区间的不同数个数
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...