四毛子算法与+-1RMQ

前言

cf群里,有人提了一个经典问题,

01010110011,形如这样的01序列,每次询问[l,r]间出现最多的连续1的个数,

区间连续1,不带修改的问题,都不带修改了,所以可以考虑更优的方法,

Claris口胡一个O(n)-O(1)的做法,于是来学习一下

思路来源

https://www.cnblogs.com/whx1003/p/13996517.html

知识总结

四毛子算法是一种暴力分块的思想,+-1RMQ是其应用之一

①+-1RMQ问题(O(n)-O(1))

+-1RMQ问题是这么一个问题,仍然询问区间的RMQ,

但是这个序列有着特殊的性质,即相邻项之差要么是-1,要么是+1,

于是,有如下的暴力思想,先分块,每一块大小为B,则分为n/B块,

对于每一块的+-1情况,二进制枚举讨论,这里以最大值为例,

这样就能判断出来最大值的位置,多个位置选择其中一个即可,

对于这n/B块,每块存了一个最大值,运用朴素ST表的思想,

这样的复杂度就是O(2^B+\frac{n}{B}*log\frac{n}{B})

为了复杂度最优,我们取B=\left \lceil \frac{logn}{2} \right \rceil,则原复杂度为O(n)级别

其实这个B值,似乎取B=logn的时候更小,

可能考虑到实现的时候还带常数吧,实践意义上除以个2更优

这样就做到了O(n)的预处理,O(1)的查询

②O(n)-O(1)查询树上两点的lca

先求出原树的欧拉序,

注意到欧拉序只有相邻深度的变化,

即深度的变化只有+-1,这样就可以套用+-1RMQ的方法,

欧拉序求a和b的lca时,需要求第一次出现a的位置和第一次出现b的位置间深度最小值的点,

于是这便可以对原序列进行+-1RMQ查询

③O(n)-O(1)求一个任意序列的RMQ

先对原序列扫一遍,建笛卡尔树,

就转化为树上问题,再套用+-1RMQ的方法,

即可实现求任意序列的RMQ

后续

考虑原问题,0011100这样的序列,

先转化一步把0合并,转化为01110,

再转化一步,把连续1压到一起,变为030,

但是这不满足+-1的渐变过程,所以考虑补出一些项来,变为0123210,

这相比原序列来说,最多扩展为原长的二倍,因此是可行的,

对于询问的[l,r]来说,可能两端的段不是完整包含的,

这个预处理一下,

对于每个位置的1,与其位于同一个尺取段内的最后位置,

和与其位于同一个尺取段内的最初位置,即可实现两端点的特判

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Code92007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值