本题有两种方法,可以用 RMQ 或者线段树。
:RMQ
就是 RMQ 模板问题,直接套模板即可。
RMQ 用的是 dp 思想。
:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int a[N], dp[N][21];
int n, m;
inline int read()
{
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
int query(int l, int r) {
int i = log2(r - l + 1);
return max(dp[l][i], dp[r - (1 << i) + 1][i]);
}
int main() {
n = read(), m = read();
for (int i = 1; i <= n; i++) {
a[i] = read();
dp[i][0] = a[i];
}
for (int j = 1; j <= 21; j++) {
for (int i = 1; i + (1 << j) - 1 <= n; i++) {
dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
}
}
while (m--) {
int l, r;
l = read(), r = read();
cout << query(l, r) << "\n";
}
return 0;
}
:线段树
可以看 这篇博客
直接给出代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 10;
int maxv[N * 4], a[N];
int n, m;
void build(int id, int l, int r) {
if (l == r) {
maxv[id] = a[l];
return;
}
int mid = (l + r) >> 1;
build(id << 1, l, mid);
build(id << 1 | 1, mid + 1, r);
maxv[id] = max(maxv[id << 1], maxv[id << 1 | 1]);
}
int query(int id, int l, int r, int x, int y) {
if (x <= l && r <= y) {
return maxv[id];
}
int mid = (l + r) >> 1;
int ans = INT_MIN;
if (x <= mid) {
ans = query(id << 1, l, mid, x, y);
}
if (y > mid) {
ans = max(ans, query(id << 1 | 1, mid + 1, r, x, y));
}
return ans;
}
inline int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') {
f = -1;
}
c = getchar();
}
while (c >= '0' && c <= '9') {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return x * f;
}
int main() {
n = read(), m = read();
for (int i = 1; i <= n; i++) {
a[i] = read();
}
build(1, 1, n);
while (m--) {
int x, y;
x = read(), y = read();
printf("%d\n", query(1, 1, n, x, y));
}
return 0;
}
线段树的复杂度是最优的。