RMQ(ST表)

RMQ (ST表)

解决区间最大(最小)问题,比起线段树的优点是在预处理log之后 查询是\(O(1)\)

//不预处理log的话也只需要使用一个log函数, 效率较高 可以看做是O(1)

缺点 不能进行修改

原题链接

题意概述:给定一个长度为\(n\)的序列 ,\(m\)次询问,每次求\(l, r\) 区间中的最大值

实现过程类似动态规划

\(f(i, j )\) 表示从 \(i\) 开始 长度为\(2^j\) 的区间的最大值

$f(i, j) $ = $ max(f(i , j - 1), f(i + 2^{j-1}, j - 1))$;

#include<bits/stdc++.h>   

using namespace std;
const int  N = 200010;

int n;
int a[200010];
int f[200010][18];

void init(){    
    for(int j = 0; j <= 17; j++)
    for(int i = 1; i + (1 << j) - 1 <= n;i ++){
       if(!j) f[i][j] = a[i];
       else f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
    }
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n ;i ++)scanf("%d", &a[i]);
    init();
    int m;
    cin >> m;
    while(m--){
        int l, r;
        scanf("%d%d", &l, &r);
        int len =  r - l + 1;
        int k =  __lg(len);
        cout << max(f[l][k], f[r - (1 << k) + 1][k]) << endl;
        
    }

}
posted @ 2022-08-02 21:40  通宵  阅读(60)  评论(0)    收藏  举报