分块入门学习笔记
引言:
对于区间问题,暴力算法(一个点一个点跳)的复杂度太高,尝试优化。可以将一些点“捆绑起来”,记录一下整体的贡献/维护信息,这样跳的时候就可以一块块跳,复杂度有很大优化。
总述:
对于一个长度为n的序列,我们可以按照一个固定的长度m,顺序将序列分成n/m+(n%m>0?1:0) 组。对于每组,我们可以进行一点处理,维护出该组的整体贡献。这样询问到包含这组的区间时,我们可以直接返回该组的整体贡献信息而非暴力查询该组的每一点;修改包含这组的区间时,可以通过打标记的方式,减少复杂度。
分析时间复杂度(块的数量与n/m同规模,为了方便,下文将n/m看做与块的数量 相等):
预处理:O(n)分块,n/m个块,若给每个块做O(x)的处理,知总复杂度:
O(n+n/m *x)
区间操作:
若该组的整体贡献可以通过维护信息O(k)得出,对于区间完整包含的块,最多有n/m个块,对每个块O(k)求出整体贡献。对区间不完整包含的块(区间左端、右端),最多有2块,2m个点,暴力枚举单点处理,设枚举一个点进行处理的复杂度为O(y)。知一次操作的复杂度:
O(n/m*k+ m*y)
综上,设有w个操作,则总复杂度:O(n+n/m*x+w*(n/m*k+ m*y))。一般取x=w=n,k=y=1,则总复杂度相当于O(n(n/m+m)) 由均值不等式知取m=sqrt(n)时复杂度最小,为O(nsqrt(n))。故块的大小常常取sqrt(n)。
(开o2才能满分的正解。。。)
题解参考大佬博客
总结:
当问题可以分解(或说可由小区间合并得到答案)时,可用线段树或分块做。
但线段树的树形结构有时候会约束它的使用,例如单点修改时要额外修改该点到根路径上的所有点,导致在线段树节点中能乱搞的力度不如分块大。
(树套树:“论单点乱搞力度谁有我大?“
(捂嘴)
分块:“闭嘴吧你,可不看看你那代码不下400行都写不完”)
分块虽然时间复杂度略逊一筹(n=1e5的情况下也慢不了多少),但块内乱搞的灵活性高(例题就是给每块内都排序,线段树做得到吗),双方各有千秋吧。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥