倍增st表
倍增st表
题目描述
给出n个数,m次询问,给出l,r的最大值/最小值,时间复杂度要求低
code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 7, M = 22;
int n, m, f[N][M], lg[N];
void init() {
for (int j = 1; j <= lg[n]; ++j)
//每次查找当前长度需要的距离
for (int i = 1; i <= n; ++i) {
//我现在在遍历长度,那么你现在肯定要由上一个状态继承
f[i][j] = f[i][j-1];
// 你现在并没有越界,所以可以进行两部分的比较
if (i+(1<<(j-1)) <= n)//当前位置的起始点
f[i][j] = max(f[i][j], f[i+(1<<(j-1))][j-1]);
}
}
int query(int x, int y) {
int s = lg[y-x+1];
// 你需要找能覆盖当前长度的最小长度
return max(f[x][s], f[y-(1<<s)+1][s]);//反推起点终点
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 2; i <= n; ++i)
lg[i] = lg[i>>1] + 1;
//覆盖长度为i的最短需要的距离,lg2(i)
for (int i = 1; i <= n; ++i)
scanf("%d", &f[i][0]);
//一开始长度为2^0=1的时候,解是自己
init();
while (m--) {
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", query(x, y));
}
}
本文由作者按照 CC BY 4.0 进行授权