基础算法--ST算法(RMQ)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_44196094/article/details/102611071

ST算法的算法的实质是倍增的产物。今天我们想以RMQ为例,介绍ST算法。

RMQ

题目:给定一段区间,用O(1)的时间复杂度访问(l,r)的最大值
输入:
10
1 2 45 7 4 1 126 1 45 7
5
1 1
1 5
2 3
4 7
6 7
输出:
1
45
45
126
126
我们先上代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>

using namespace std;

const int N=1010;
int n;
int f[N][N],d[N];

void work(){
    for(int i=1;i<=n;i++) f[i][0]=d[i];
    int t=log(n)/log(2)+1;
    for(int j=1;j<t;j++)
        for(int i=1;i<=n-(1<<j)+1;i++)
            f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}

int query(int l,int r)
{
    int k=log(r-1+1)/log(2);
    return max(f[l][k],f[r-(1<<k)+1][k]);
}
int main(){
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>d[i];
    work();//预处理
    int T;
    cin>>T;
    while(T--)
    {
        int l,r;
        cin>>l>>r;
        cout<<query(l,r)<<endl;
    }

    return 0;
}

这道题有点像动态规划,我们用f[i][j]表示[i,i+2j-1]的状态,我们把这些状态枚举一遍,注意c++里面的log方法是求ln,我们用换底公式变成求log,动态规划的状态转移方程的意思是f[i][j]的max要么是出现在[i,i+2(j-1)-1]要么出现在[i+2j-1,i+2j-1]就是这样,然后我们说说查询,原理比较简单,和状态转移类似,就是会出现重复区间,但是不要怕,只要不越界,重复区间不会影响我们的结果。

猜你喜欢

转载自blog.csdn.net/qq_44196094/article/details/102611071