RMQ问题模板

#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000+10
int dp[MAXN][MAXN], a[MAXN]; 

void InitRMQ(int l, int r, int n){
    int k = floor((double)log(r-l+1)/log(2));
    for (int i = 1; i <= n; ++i) dp[i][0] = a[i];
    for (int j = 1; j <= r-l+1; ++j)
        for (int i = 1; i+(1<<j-1) <= r; ++i)
            dp[i][j] = max(dp[i][j-1], dp[i+(1<<j-1)][j-1]); 
}

int getmax(int l, int r){
    int k = floor((double)log(r-l+1)/log(2));
    return max(dp[l][k], dp[r-(1<<k)][k]);
}

int main()
{
    int n, q;
    cin>>n>>q;
    for (int i = 1; i <= n; ++i) cin>>a[i];
    InitRMQ(1, n, n);
    int l, r;
    while(q--){
        cin>>l>>r;
        cout<<getmax(l, r)<<endl;
    }

    return 0;
}
ST 表是一种基于树形结构的数据结构,用于处理区间查询和更新操作。它通过预处理的方式将原始数据存储在树状结构中,以支持高效的区间查询。其构建时间复杂度为 O(nlogn),构建完成后可在 O(logn) 的时间内进行区间查询和更新操作 [^1]。 ### 解决方案 #### 1. 预处理 设 `f[i][j]` 表示以 `i` 为左端点,长度为 `2^j` 的区间的最小值(最大值等)。以最小值为例,有递推式: - 当 `j = 0` 时,`f[i][j] = a[i]`; - 当 `j > 0` 时,`f[i][j] = m(f[i][j - 1], f[i + 2^(j - 1)][j - 1])`。 建出来的 `f` 数组即为一个 ST 表,中间的操作用位运算实现 [^3]。 #### 2. 处理查询 对于查询区间 `[x, y]`,令 `s = lg[y - x + 1]`,则区间 `[x, y]` 的最大值为 `max(f[x][s], f[y - (1 << s) + 1][s])` [^4]。 ### 使用指南 以下是一个使用 Python 实现 ST 表解决 RMQ 问题的示例代码: ```python import math # 预处理 ST 表 def build_st_table(arr): n = len(arr) log_n = int(math.log2(n)) + 1 st = [[0] * log_n for _ in range(n)] # 初始化 j = 0 的情况 for i in range(n): st[i][0] = arr[i] # 递推计算 ST 表 for j in range(1, log_n): for i in range(n - (1 << j) + 1): st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]) return st # 处理查询 def query(st, x, y): s = int(math.log2(y - x + 1)) return max(st[x][s], st[y - (1 << s) + 1][s]) # 示例使用 arr = [1, 3, 2, 7, 9, 4, 6] st = build_st_table(arr) x, y = 1, 4 # 查询区间 [1, 4] result = query(st, x, y) print(f"区间 [{x}, {y}] 的最大值为: {result}") ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值