RMQ中的ST算法模板

1 篇文章 0 订阅

最近也算是比较系统的整理了一下ST算法。大概把算法的意思写在了下面这张图里


然后是贴模板了。

/*
 * 下标从1开始的数组val[1~n]。最大询问区间1~n
 * initRMQ(n) O(nlogn) 
 * call: getval(a,b) O(1)
 */
int val[M];
int Max[20][M]; //max[i][j] 从j开始的,连续2^i个数字的最大值
//int Min[20][M];//min[i][j]  从j开始的,连续2^i个数字的最小值
int idx[M];//等价于 (int)log(1.0*m)/log(2.0) 若空间不足可以这样写

#define lst(L1,L2) ((L1)-(L2)+1) //求与区间长度为L1共同的右端点的长度为L2的区间的左端点。
void initRMQ(int n) {
	idx[0]=-1;
	for(int i=1;i<=n;i++) {
		idx[i]=(i&(i-1))?idx[i-1]:idx[i-1]+1;
		//Min[0][i] = val[i];
		Max[0][i] = val[i];
	}
	
	for(int i=1;i<=idx[n];i++){
		int m=lst(n,1<<i);
		for(int j=1;j<=m;j++){
			//Min[i][j]=min(Min[i-1][j],Min[i-1][j+(1<<i>>1)]);
			Max[i][j]=max(Max[i-1][j],Max[i-1][j+(1<<i>>1)]);
		}
	}
}
int getval(int a,int b) {
	int t=idx[b-a+1];
	int s1=a;
	int s2=lst(b,1<<t);
	return max(Max[t][s1],Max[t][s2]);
	//return min(Min[t][s1],Min[t][s2]);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值