用ST算法(ST表) 求解RMQ(区间最值)问题

时间:2019-09-27
本文章向大家介绍用ST算法(ST表) 求解RMQ(区间最值)问题,主要包括用ST算法(ST表) 求解RMQ(区间最值)问题使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

//poj 3264

//O(n log(n) )

//只能用于静态数据,并且只能求区间最大或者最小

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int MAXN = 5e4+5;
 8 
 9 int n, m; // n个数 m次查询
10 int a[MAXN];
11 int maxn[MAXN][32];// f[i][j] 表示从第i位起的 2^j 个数中的最大值 区间[i, i+(1<<j)-1]
12 int minn[MAXN][32];
13 
14 void ST() {
15     for(int i = 1; i <= n; ++i) maxn[i][0] = minn[i][0] = a[i];
16     int m = (int)log2(n*1.0)/log2(2*1.0);
17     for(int j = 1; j <= m; ++j) {
18         for(int i = 1; i+(1<<j)-1 <= n; ++i) {
19             maxn[i][j] = max(maxn[i][j-1], maxn[i+(1<<(j-1))][j-1]);
20             minn[i][j] = min(minn[i][j-1], minn[i+(1<<(j-1))][j-1]);
21         }
22     }
23 }
24 
25 int query(int l, int r) {
26     int k = log2(r-l+1)/log2(2);
27     return max(maxn[l][k], maxn[r-(1<<k)+1][k]) - min(minn[l][k], minn[r-(1<<k)+1][k]);
28 }
29 
30 int main() {
31     scanf("%d%d", &n, &m);
32     for(int i = 1; i <= n; ++i) {
33         scanf("%d", &a[i]);
34     }
35     ST();
36     int l, r;
37     for(int i = 0; i != m; ++i) {
38         scanf("%d%d", &l, &r);
39         printf("%d\n", query(l, r));
40     }
41     return 0;
42 }

//详解见https://blog.csdn.net/a_bright_ch/article/details/81062039

原文地址:https://www.cnblogs.com/pupil-xj/p/11595456.html