RMQ问题 Page 41 ST算法

RMQ问题 Page 41 ST算法

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

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

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

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

接下来很容易理解的转移方程, i i 开始的 2 j 2^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]);
		}
	}
}

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

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

取一个 k k ,满足 2 k r l + 1 < 2 k + 1 2^k \leq r-l+1<2^{k+1} ,那么以 l l 为开头开始的 2 k 2^k 个数和以 r r 结尾的 2 k 2^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 ( n l o g n ) O(nlogn)

查询: O ( 1 ) O(1)

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

刚开始学 继续钻研

发布了125 篇原创文章 · 获赞 8 · 访问量 9110

猜你喜欢

转载自blog.csdn.net/w_udixixi/article/details/104794325