题目地址:
https://www.acwing.com/problem/content/description/1272/
输入一串数字,给你 M M M个询问,每次询问就给你两个数字 X , Y X,Y X,Y,要求你说出 X X X到 Y Y Y这段区间内的最大数。
输入格式:
第一行两个整数
N
,
M
N,M
N,M表示数字的个数和要询问的次数;接下来一行为
N
N
N个数;接下来
M
M
M行,每行都有两个整数
X
,
Y
X,Y
X,Y。
输出格式:
输出共
M
M
M行,每行输出一个数。
数据范围:
1
≤
N
≤
1
0
5
1≤N≤10^5
1≤N≤105
1
≤
M
≤
1
0
6
1≤M≤10^6
1≤M≤106
1
≤
X
≤
Y
≤
N
1≤X≤Y≤N
1≤X≤Y≤N
数列中的数字均不超过
2
31
−
1
2^{31}−1
231−1
典型的RMQ问题。代码如下:
#include <iostream>
#include <cmath>
using namespace std;
const int N = 1e5 + 10, M = log2(N) + 1;
int n, m;
int a[N];
int f[N][M];
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
f[i][0] = a[i];
}
int J = log2(n) + 1;
for (int j = 1; j <= J; j++)
for (int i = 1; i + (1 << j) - 1 <= n; i++)
f[i][j] = max(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
while (m--) {
int l, r;
scanf("%d%d", &l, &r);
int k = log2(r - l + 1);
printf("%d\n", max(f[l][k], f[r - (1 << k) + 1][k]));
}
return 0;
}
预处理时间复杂度 O ( n log n ) O(n\log n) O(nlogn),每次询问时间 O ( 1 ) O(1) O(1),空间 O ( n log n ) O(n\log n) O(nlogn)。