【题解】P5609 | 线段树 分段函数维护 人类智慧
对数据结构的爱,未曾衰减?
本题解参考了 Saliеri 的题解。
首先对于这类数经过操作求最终值的问题,可以比较简单地想到一个分块做法:
将序列分块,每块长度为 ,对于每一块我们需要维护某个值进去会以另外某个值出来,然后就可以在在整块上快速查询然后模拟散块,考虑这个某个值进去会以另外某个值出来的函数,令其为 ,容易发现 是一个分段函数且每段是一次函数,其段数是 的,考虑对于每个块求出这个分段函数。
维护该分段函数的分界点 进入该区间后出来且至少减去了 个 的最小值。
引理: 单增且 。
证明:因为 是最小的满足至少减去了 个 的值,考虑减去 次 后一定变成了 或负数,至少需要加上 才会能够继续减。
考虑增量维护 ,新的 发生改变仅当加上新加入的这个 后可以减去 ,即 可以被如下更新:
需要满足能够在前面部分减去 并加上 后大于等于 ,故需要满足如下条件:
且需要满足条件 ,该条件意味着 能够满足在这次能被减去的数不能在之前被减去了超过 次,否则到该数时的值就不是 了,可能会减去更多。
所以我们就有了个 的做法,但是不太能过,应该怎么继续下去找到一个 的做法?
之所以要分块是因为这个分段函数看上去很不可多元合并,只可以单元添加,如果可以多元合并就可以建出线段树,因为本题中的分段函数性质很特殊,考虑设计如下一种合并方式:
枚举在左侧和右侧的被减去的次数 ,试图判断能否在整个区间构成减去 次的情况,记录左侧的和为 ,则有如下更新:
类似上面,若满足条件 才可以去更新,即在左侧被减去了 次,否则会减去 次或更多。
对于满足条件的 有如下更新:
直接枚举 并进行合并的复杂度是平方的,我们继续挖掘性质。
令 。
定理:对于一个固定的 ,被 最小的 更新到是最优的。
证明:试比较 ,因为有 ,所以一定有 。
所以我们只需要对每个 求出最小的 可以去更新它,又因为可以更新的条件是 ,随着 增大而越来越松,所以用双指针枚举最大的 即可。
于是我们求出了所有线段上的分段函数的形态,查询时直接在线段树上依次对 个分段函数进行二分,时间复杂度 。
本文已经结束了。本文作者:ღꦿ࿐(DeepSea),转载请注明原文链接:https://www.cnblogs.com/Dreamerkk/p/17970895,谢谢你的阅读或转载!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步