RMQ问题 Page 41 ST算法
http://www.51nod.com/Challenge/Problem.html#!#problemId=1174
第一次写博客 这是51nod上一个简单的基础题。
大致题意:给一组数组 让你判断T个区间里的最大值(或最小值)。
分析:暴力肯定会TLE。
根据倍增思想,需要引入2的整数次幂用来简化时间和空间,那么具体该怎么做呢?
先取数组,表示从开始的个数中的最大值,即区间。
接下来很容易理解的转移方程,从开始的个数中的最大值肯定是其左半段和右半段的最大值,这个左半段和右半段完美契合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的整数次幂应该如何处理?
只需要直接覆盖即可,不过这个覆盖不是随便覆盖,范围肯定是不能超出给出的的
取一个,满足,那么以为开头开始的个数和以结尾的个数肯定覆盖了整个区间~
查询代码如下:
int ST_query()
{
int k=log(r-l+1)/log(2);
return max(dp[l][k],dp[r-(1<<k)+1][k]);
}
综上所述:
ST算法的时间复杂度为:
预处理:
查询:
RMQ问题同样可以用线段树解决,倍增思想实在是好。
刚开始学 继续钻研
来源:CSDN
作者:w_udixixi
链接:https://blog.csdn.net/w_udixixi/article/details/104794325