RMQ & ST

1. 什么是 RMQRMQ

RMQRMQ 是英文 Range Maximum (Minimum) QueryRange\ Maximum \ (Minimum) \ Query 的缩写,顾名思

义是用来求某个区间内的最大值或最小值,通常用在要多次询问一些 区间最值区间最值

的问题中。

2. 求解 RMQRMQ 问题

今天我们要用的是—— STST 表。

注意的是,ST表只用于静态区间求最值,而动态区间就只能用 线段树树状数 组 了。

3. STST

STST 表的功能很简单

它是解决 RMQRMQ 问题(区间最值问题)的一种强有力的工具

它可以做到 O(nlogn)O(nlogn) 预处理, O(1)O(1) 查询最值

STST 算法思想

ST表是利用的是 倍增 and DP倍增 \ and \ DP 的思想

拿最大值来说

我们用 dp[i][j]dp[i][j] 表示,以 ii 位置为起点的 2j2^j 个数中的最大值,例如 dp[2][3]dp[2][3]

示的是 以 22 位置为起点的 232^3 个数中的最大值,即 22 位置和 77 位置中两个数的最

大值

初始化 dp[i][0]=aidp[i][0]=a_i

那么转移的时候我们可以把当前区间拆成两个区间并分别取最大值

dp[i][j]=max(dp[i][j1],dp[i+(1<<(j1))][j1])dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1])

在这里插入图片描述

查询时我们先计算出 log2(区间长度)log2(区间长度)

然后对于左端点和右端点分别进行查询,这样可以保证一定可以覆盖查询的区间

在这里插入图片描述ANS=min(dp[l][k],dp[r(1<<k)+1][k])ANS = min(dp[l][k], dp[r - (1 << k) + 1][k])

AC codeAC \ code

模板题

#include <bits/stdc++.h>
using namespace std;

#define max(a, b) a > b ? a : b
const int maxn = 1e5 + 5;
int n, m;
int a[maxn][21];
int lg[maxn];
void update()
{
    for (int j = 1; (1 << j) <= n; j++)
    {
        for (int i = 1; i + (1 << j) - 1 <= n; i++)
        {
            a[i][j] = max(a[i][j - 1], a[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int query(int l, int r)
{
    int t = lg[r - l + 1] - 1;
    return max(a[l][t], a[r - (1 << t) + 1][t]);
}
signed main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i][0];
    }
    for (int i = 1; i <= n; ++i)
    {
        lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
    }
    update();
    for (int i = 1; i <= m; i++)
    {
        int l, r;
        cin >> l >> r;
        cout << query(l, r) << endl;
    }
}
posted @ 2021-05-20 21:39  蒟蒻orz  阅读(3)  评论(0编辑  收藏  举报  来源