离线 log 算法
CDQ分治
一种空间复杂度(和时间常数?)优秀的离线算法。
简介:对于偏序问题,将其中一维(记为
一般顺序,可以用于偏序计数问题:
void cdq(int l, int r){
if(l==r) return ;
int mid=(l+r)/2;
cdq(l, mid); cdq(mid+1, r);
work...
}
例题:
P3810 【模板】三维偏序(陌上花开)
P4169 [Violet]天使玩偶/SJY摆棋子
对于偏序计数的常见trick,有加入时间维离线,可以解决较为简单的动态问题。
例题:
P3157 [CQOI2011]动态逆序对
在cdq辅助转移偏序dp时,顺序会变为
void cdq(int l, int r){
if(l==r) return ;
int mid=(l+r)/2;
cdq(l, mid);
work...
cdq(mid+1, r);
}
考虑在dag模型类dp过程中,用来转移的状态应是转移完全完成的。这种转移可以保证用
例题:
P2487 [SDOI2011]拦截导弹
P4093 [HEOI2016/TJOI2016]序列
cdq同样可以用于带修问题中。具体的,将修改和询问都加入时间维后放在一个序列中,仿照上文的trick将时间维cdq掉。我们需要考虑的就是每一个 修改-询问 的点对中修改对询问的影响。这需要修改具有可叠加性,即前面的修改需要被后面的修改覆盖时易取消。
总结:
正常处理k维偏序相关的题目时,对一维扫描,则余下k-1维必须使用数据结构动态维护。而cdq分治对于第一维采用分治处理,消去了第一维的影响,故可以扫描第二维,余下k-2维使用数据结构。
而cdq的好处是,在通常最高是三维的问题中,二维数据结构的空间复杂度普遍在
整体二分
针对一类包含多组询问,单独的一个询问可以通过在答案值域上二分解决的题目的算法。通过遍历二分答案的过程中可能产生的值域(可以想象成答案值域形成的线段树上的全体区间),一次性确定所有询问的答案。可以发现其求得答案的顺序和询问顺序无关(事实上是按答案值域递增的顺序),故其为离线算法。
分析节省时间复杂度的原理。我们设答案值域大小为
题目示例:
P3332 [ZJOI2013]K大数查询
P3834 【模板】可持久化线段树 2
线段树分治
一种解决一类特殊带修问题的算法。
一个问题需要使用线段树分治,一般有以下特点:
1.有多组修改,每个修改的影响持续一个时间段
2.修改操作的复合满足交换律(即与顺序无关)。
3.对于可行的维护方法,修改操作在与其他修改复合过后难以撤销。可以理解为只容易撤销末尾的操作(沿着操作栈撤销)。
4.多组询问,每次询问的时间不同。
我们考虑将时间轴建成线段树,每一个操作对应的时间段可以在对应
题目示例:
P9168 [省选联考 2023] 人员调度
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现