其他分享
首页 > 其他分享> > 天才的记忆(RMQ,ST表)

天才的记忆(RMQ,ST表)

作者:互联网

原题链接

分析

裸的ST表

ST表

初始化

倍增枚举出区间的最大值,f[N] [M]代表,从n开始长度为2^m的区间最值。

查询

[l,r]

1.求出该区间长度最接近的倍增预处理后的长度,k = log(len)/log(2);

2.最大值为

\[Max=max(f[l][k],f[r-2^k+1][k]) \]

ACcode

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10,M = 18;
int f[N][M];
int w[N];
int n,m;
//初始化
void init()
{
    for(int j=0;j<18;j++)//枚举区间长度
        for(int i=1;i+(1<<j)-1<=n;i++)//枚举区间
        {
            if(!j) f[i][j]=w[i];//如果区间长度为1,则就是它本身
            else f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);//否则,则最大值为[i,i+2^(j-1)]和[i+2^(j-1),i+2^j]中的最大值
        }
}

int query(int l,int r)
{
    int len = r-l+1;
    int k = log(len)/log(2);//从区间开头,得到的最长的预处理的区间
    return max(f[l][k],f[r-(1<<k)+1][k]);//这个区间的最大值,是[l,l+2^k],[r-2^k+1,r]中的最大值
}

int main()
{
    scanf("%d", &n);
    for(int i=1;i<=n;i++) scanf("%d",&w[i]);
    init();
    scanf("%d",&m);
    while (m -- ){
        int l,r;
        scanf("%d%d",&l,&r);
        printf("%d\n",query(l,r));
    }
    return 0;
}

标签:初始化,RMQ,log,int,最大值,ST,天才,长度
来源: https://www.cnblogs.com/aitejiu/p/15171988.html