根号分治与莫队算法

1.根号分治与分块

在预处理与询问的复杂度之间寻找平衡的一个算法,通常以根号为分界线。属于智慧的暴力。

1.1. 根号平衡

使用数学不等式对于阈值取一个值,使得复杂度最优。如果有阈值 \(B\),若问题有一部分暴力可以 \(O(B)\) 解决,另一部分可以 \(O(\frac{n}{B})\) 解决。那么根据基本不等式 \(a+b\geq 2\sqrt{ab}\)\(B=\sqrt{n}\) 复杂度最优。这称之为根号平衡

1.2 分块

对于整块直接查询 \(O(\frac{n}{B})\),对于单点暴力修改 \(O(nB)\),使用根号平衡。得到一个暴力的数据结构,需要灵活地分析。

1.3 例题

I.

CF1207F Remainder Problem

对于询问,大于 \(\sqrt{n}\) 的暴力,小于的维护一张表 \(f_{i,j}\) 表示编号模 \(i\)\(j\) 的数的总和

II.

Luogu P8572

首先前缀和容易想到,接着讨论 \(n,k\) 大小关系,\(n<k\) 可以打表,\(n>k\) 可以询问暴力查询。

III.

abc335_f

给读者留作思考练习

2.莫队算法

对于区间问题,常常会使用线段树维护,但是对于一些数据合并复杂度无法 \(O(1)\) 解决。所以不能使用,应当使用莫队算法。对于离线处理的查询问题,通过合理安排这些计算的次序,得到一个较优的复杂度

2.0 历史

关于莫队的来历,要知道这是一些OIer暴力时偶然得到的智慧结晶。

有些东西是做出来的,不是学出来的。

其实莫队是由莫涛队长系统总结并宣传的一种算法,由此命名。

2.1 例题

一个长度为 \(n\) 的序列,询问 \(m\)\([L,R]\) 的区间内至少重复三次的数有多少。

应当暴力,拓展L,R边界。以查询左端点所在块为第一关键字、右端点大小为第二关键字,从小到大排序。

2.2 莫队拓展

2.2.1 带修莫队

问题加入修改

记录指令修改前后的值,记录查询时做过几次修改,对询问排序的优先级改为:第一关键字 L 所在块,第二关键字 R 所在块,第三关键字,做了几次修改。

然后暴力,带上更改到对应修改时间的操作。

2.2.2 回滚莫队

操作加入容易,删除难

询问排序相同,枚举左端点所在的块的所有询问。

左右端点在同一块的暴力统计,否则记录一个块尾到当前右端点的区间,每次暴力回滚添加元素,然后回溯还原。

2.2.3 树上莫队

问题在树上

将树变成一个序列,然后莫队处理。

posted @ 2024-02-26 23:06  妖灵梦  阅读(40)  评论(0)    收藏  举报