RMQ阶段总结(一)

进行RMQ或类似问题可以采用如下思路:

一、暴力求解

通常用于对拍或实在想不出更好的方法时。最坏情况下的复杂度一般达到 O ( n ) O(n) O(n),只能通过较弱的的数据。

二、分块

通过将数据分为 ⌊ n ⌋ \lfloor {\sqrt n}\rfloor n 块,每块维护相应数据(和、最大值、最小值等),注意如果存在区间修改时要设置标记。时间复杂度降至 O ( n ) O(\sqrt n) O(n ),在想不到如何用更好的方法(线段树、树状数组等)实现、题目时间限制不紧或做题时间比较紧时,可以尝试。

有关用分块处理的各类RMQ问题,参考这篇博客

三、线段树

线段树可以处理符合结合律的各种操作,如区间加、区间乘、区间异或等。复杂度为 O ( l o g n ) O(log n) O(logn)但常数较大。
如果存在区间修改操作,应当设置懒标记。对于给定的运算 ⊕ \oplus ,懒标记下放的方法为:

tag[son]=tag[fa];
data[son]=(⊕运算对数据的影响,如加法为+=tag[fa]*child_len,
乘法为*=tag[fa])

如果有多个区间修改操作,应当人为给懒标记确定顺序。必须考虑:

  • 确定为后更新的操作对应的懒标记,先更新的操作对它的影响
  • 两种操作分别如何作用于数据

比如:加、乘两种操作,确定为先乘后加,那么,两种操作对数据的作用如下:

  • 加法:new_data=data+length*add_tag
  • 乘法:new_data=data*mul_tag

后进行的操作为加法,乘法对它的影响为:需要乘上之前乘过的值,即new_add_tag=add_tag*length

四、树状数组

树状数组是简化的线段树,比线段树常数小。适用于单点修改、区间查询的情况。如果是涉及到前缀和操作的区间修改,也可以考虑采用差分的方法间接使用。

树状数组通过将结点转化为二进制求解。如进行单点加操作:

while(i>0) {
	bit[i]+=val;
	i-=lowbit(i);
}

区间查询([1,i]):

while(i<=n) {
	res+=bit[i];
	i+=lowbit(i);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值