【模版】ST表求区间最值
参考地址:https://www.cnblogs.com/qq965921539/p/9608980.html
写在前面
ST表的简介
ST表类似树状数组、线段树这两种算法,是一种用于解决RMQ(Range Minimum/Maximum Query)即区间最值查询问题的离线算法
ST表的主体是一个二维数组ST[i][j]
,表示需要查询的数组的从下标i
到下标i+2^j - 1
的最值
ST表的用处
快速查询区间最值
ST表的优势
预处理复杂度同为O(nlogn)
查询时间复杂度为O(1)
ST表的局限性
一、ST表一般不能维护区间和
二、不支持动态修改
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define MaxSize 100010 //注意依题修改数组大小
using namespace std;
int a[MaxSize]; //原始数组
int ST[MaxSize][MaxSize]; //ST表
void Init(int n){ //ST表的初始化
for (int i = 0; i < n; i++) ST[i][0] = a[i]; //将原数组放在第一列
for (int i = 1; (1 << i) <= n; i++)
for (int j = 0; j+(1<<i)-1 < n; j++)
ST[j][i] = max(ST[j][i-1], ST[j+(1 << (i-1))][i-1]); //ST原理
}
int Search(int l, int r){ //查询区间最大值
int k = (int)(log((double)(r-l+1)) / log(2.0));
return max(ST[l][k], ST[r-(1 << k)+1][k]); //ST原理
}
int main() {
int n, q; //点个数 查询个数
scanf("%d%d", &n, &q);
for (int i = 0; i < n; i++) scanf("%d", &a[i]); //获取元素值
Init(n); //ST表初始化
int l, r; //查询左右区间
for (int i = 1; i <= q; i++){
scanf("%d%d", &l, &r);
printf("%d\n", Search(l-1, r-1)); //依题判断下标从一开始则减一
}
return 0;
}