线段树优化

概述

  • 线段树优化通过线段树能快速区间取值和区间修改的特性,高效实现具有连续性的 dp 转移。

  • 所谓的连续性可以是顺推的转移目标点为连续区间,也可以是逆推的转移出发点为连续区间,这一连续不一定必须是原数组下标这一维度上的。

  • 效果一般为将 KD1D 的 dp 的 O(n) 的转移优化至 O(log),转移大于 1D 的 dp 中线段树优化较为罕见。

  • 应当指出的是,有些时候要刻意使用同构 dp 来方便进行线段树优化,譬如一个典型的手法是将“考虑了前 i 个,最后一个选的是 j”改成“考虑了前 i 个,最后一个选的是 i”,将状态的复杂度转嫁到转移上,然后使用线段树优化。

例题

CF1788E Sum Over Zero

  • 题意略。赛时我可能智商欠费。

  • 容易看出一个线段 [l,r] 合法当且仅当 psrpsl10。可以转换成 psrpsl1,这里 ps 是 perfix sum 的缩写。

  • 故考虑设计如下 dp:

    • 状态设计:fi 表示考虑了前 i 个点,当前最大合法总长度是多少。

    • 初始化:f0=0

    • 状态转移方程:fi=max(fi1,maxj=0i1(maxk=1jfk+(ij))),其中后一个转移需要满足 psipsj

    • 不妨记 gi=maxj=1ifi,显然可以预处理,稍微化一下式子(只考虑后一种转移),得到 maxj=0i1(gjj)+i。事实上因为前一种转移,g 本身就具有 g 的性质,不过这里我们假装它没有。

    • 注意到我们的转移顺序天然地保证了 j<i,故我们可以开一棵值域线段树,树上第 i 个叶节点表示 maxpsj=i(gjj)。在得到 gx 后将 gxx 扔到树上的第 psx 个叶节点上,转移的时候只要做前缀询问就好了。

    • 那其实应该也可以是树状数组,单点修改,前缀最大值...哦值域太大了啊。那么考虑将这一转移对偶,即我们就开关于下标的树,此时转移顺序变成按 ps 从小到大了。哦错了,这会使得前一种转移不可行,于是炸了。

  • 复杂度 O(nlog)

9.25 T3 蜜蜂搬家

posted @   未欣  阅读(64)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示