RMQ

RQM(即 Range Minimum/Maximum Query):区间最值查询。

可以先进行预处理,然后查询,预处理的时间复杂度为O(nlog(n)),查询为O(1)吧。

设dp【i,j】为区间i~i+2^j-1的最值,就如dp【1,0】为【1,1】的最值,dp【1,1】为【1,2】的最值,dp【1,2】为【1,4】的最值。

那么初始化dp【i,0】=a【i】;

状态转移方程为dp【i,j】=min(dp【i】【j-1】,dp【i+(1<<(j-1)】【j-1】);

void init(int n){
	for(int i=1;i<=n;i++){
		dp[i][0]=a[i];
	}
	for(int i=1;(1<<i)<=n;i++){
		for(int l=1;l+(1<<i)-1<=n;l++){
			dp[l][i]=min(dp[l][i-1],dp[l+(1<<(i-1))][i-1]);
		}
	}
}

  

查询:

查询区间【l,r】的最值,首先找到j:j=floor(log(r-l+1)/log(2))

那么【l,r】的最值为:min(dp【l】【j】,dp【r-(1<<(j)+1】【j】)

比如,某序列为:5 4 3 2 1,此时查询【1,5】,首先j=floor(log(5)/log(2)=2);查询结果为min(dp【1】【2】,dp【2】【2】),即min(【1,4】,【2,5】)。

int rmq(int l,int r){
	int j=floor(log(r-l+1)/log(2));
	return min(dp[l][j],dp[r-(1<<j)+1][j]);
}

  

转载于:https://www.cnblogs.com/Zhi-71/p/10710082.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值