忠诚
题目大意:
有 m 笔帐, n 个查询。
按照顺序输入 m 笔帐, n 此询问 a 到 b 里最小的帐。
题解:
很明显可以看出是求区间最小值问题。
线段树可以做,但是这题用RMQ就可以了。
代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int maxn = 1e5+10;
int n, q;
int l, r;
int bill[maxn], fa[maxn][35];
void Init(){
scanf("%d %d", &n, &q);
for(int i = 1; i <= n; ++i){
scanf("%d", &bill[i]);
}
}
void RMQ(){
for(int i = 1; i <= n; ++i){
fa[i][0] = bill[i];
}
for(int i = 1; i <= 20; ++i){
for(int j = 1; j <= n; ++j){
if(j+(1<<i)-1 <= n){
fa[j][i] = min(fa[j][i-1], fa[j+(1<<i>>1)][i-1]);
}
}
}
}
void Solve(){
for(int i = 0; i < q; i++){
scanf("%d %d", &l, &r);
int t = floor(log2(r-l+1));
//int k = floor(log2(r-l+1));
printf("%d ", min(fa[l][t], fa[r-(1<<t)+1][t]));
//printf("%d\n", min(fa[l][k], fa[r-(1<<k)+1][k]));
}
}
int main(){
Init();
RMQ();
Solve();
return 0;
}