【学习笔记】倍增分块
倍增分块常用于处理数值递减/递增的问题,形如当 时,使 。
分成 的若干块。
P4587
暴力就是排个序,然后便利值域,依次加入。加入完 时,遍历到值域第一个不能被组成的位置 , 的数都是可以被已经加入的数组成的,所以 一定不能大于 。一旦大于 , 这个位置就不能被表示了。那么 ,加入 会使得下一个不能被组成的位置是 。找到第一个不行的就行。
考虑优化这个过程,注意到 是单增的,所以用倍增分块。设当前在 ,那么要往后加数,下一个数必然不能大于 。所以可以查询 的最小值,如果最小值小于等于 ,那么由于最小值 ,所以 ,那么这一块的所有数必定可以取走,所以就取走 所有数加到 里面。每个块预处理用个 st 表就行,复杂度 。
CF1515I
出现了形如 ,。考虑按要求排序,然后模拟这个过程,发现有时候会遇到一个比 大的数取不了跳过,很难受。那么可以考虑特殊处理这些,设当前 ,那么只要取到一个在 的数必然就会降级为至多 。所以关注那些 的数,如果这个都取到某个数都不能取了,那么那时候肯定是 。
那么该怎么找到这样一个数呢,考虑在线段树上维护所有 的重量和 ,那么可以线段树二分找到第一个 的位置,这是第二种情况。再考虑第一种,显然 要大于这个 的重量和之前所有 的重量和,设这两者的和是 ,那么 还得小于之前所有 物品的那些 值,可以用线段树二分求出。
所以每次 ,做最多 次,复杂度单次是 。
本文作者:FantasyNumber
本文链接:https://www.cnblogs.com/MiniLong/p/18297265
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步