这是最基础的一类线段树问题。将区间扩展为2^n的形式。一律采用左闭右开区间。结点序号从0开始。
一律采用左闭右开区间。结点序号从0开始。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <climits>
using namespace std;
const int maxn = 1<<17;
const int inf = INT_MAX;
int n;
int dat[2*maxn-1];
void init(int N){
n = 1;
while(n < N) n <<= 1; //扩展线段长度到2的整数次幂
for(int i=0; i<(n<<1)-1; i++) //序号从0开始
dat[i] = inf;
}
void update(int k, int a){ //单点更新
k += n-1;
dat[k] = a;
while(k > 0){
k = (k-1)/2;
dat[k] = min(dat[k*2+1], dat[k*2+2]);
}
}
int query(int a, int b, int k, int l, int r){ //左闭右开区间
if(r <= a || b <= l) return inf;
else if(a <= l && r <= b) return dat[k];
else{
int vl = query(a, b, k*2+1, l, (l+r)/2);
int vr = query(a, b, k*2+2, (l+r)/2, r);
return min(vl, vr);
}
}
int main(){
int N;
cin>>N;
init(N);
int e;
for(int i=0; i<N; i++){
cin>>e;
update(i, e);
}
int q;
cin>>q;
while(q--){
int a, b;
cin>>a>>b; //左闭右开区间
int res = query(a, b, 0, 0, n); //注意是扩展区间n
cout<<res<<endl;
}
return 0;
}
一律采用左闭右开区间。结点序号从0开始。