RMQ问题 Page 41 ST算法

时光怂恿深爱的人放手 提交于 2020-03-11 14:43:02

RMQ问题 Page 41 ST算法

http://www.51nod.com/Challenge/Problem.html#!#problemId=1174
第一次写博客 这是51nod上一个简单的基础题。

大致题意:给一组数组 让你判断T个[l,r][l,r]区间里的最大值(或最小值)。

分析:暴力肯定会TLE。
根据倍增思想,需要引入2的整数次幂用来简化时间和空间,那么具体该怎么做呢?

先取数组dp[i][j]dp[i][j],表示从ii开始的2j2^j个数中的最大值,即区间[i,i+2j1][i,i+2^j-1]

接下来很容易理解的转移方程,ii开始的2j2^j个数中的最大值肯定是其左半段和右半段的最大值,这个左半段和右半段完美契合2的整数次幂思想,只需要把幂次-1即可!

dp[i][j]=max(dp[i][j-1],dp[i+1<<(j-1)][j-1]);

预处理代码如下:

void ST()
{
	for (int i=1;i<=n;i++)dp[i][0]=a[i];//区间长度为1的区间最大值为本身
	int t=log(n)/log(2)+1;
	for (int j=1;j<t;j++)
	{
		for (int i=1;i<=n-(1<<j)+1;i++)
		{
			dp[i][j]=max(dp[i][j-1],dp[i+1<<(j-1)][j-1]);
		}
	}
}

接下来就是查询问题了,如果区间长度正好是2k2^k,那么我们可以直接取dp[r2k+1][k]dp[r-2^k+1][k]作为答案,那么如果区间不正好是2的整数次幂应该如何处理?

只需要直接覆盖即可,不过这个覆盖不是随便覆盖,范围肯定是不能超出给出的[l,r][l,r]

取一个kk,满足2krl+1<2k+12^k \leq r-l+1<2^{k+1},那么以ll为开头开始的2k2^k个数和以rr结尾的2k2^k个数肯定覆盖了整个区间~

查询代码如下:

int ST_query()
{
	int k=log(r-l+1)/log(2);
	return max(dp[l][k],dp[r-(1<<k)+1][k]);
}





综上所述:

ST算法的时间复杂度为:

预处理:O(nlogn)O(nlogn)

查询:O(1)O(1)

RMQ问题同样可以用线段树解决,倍增思想实在是好。

刚开始学 继续钻研

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!