线段树基本应用——区间最值查询

来源:互联网 发布:软件源闪退怎么办 编辑:程序博客网 时间:2024/06/06 07:45

感觉对线段树快有阴影了。。还是先从最简单的开始吧。关键是理解原理。

求区间最小值:

题目:

2 //testcases

 

5 3  //n:数组元素个数,m:查询次数

78 1 22 12 3  //输入数组,每个数最大值不超过10^5

1 2     //查询从l到r上的最小值

3 5

4 4


#include <cstdio>#include <algorithm>#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1using namespace std;const int maxn = 105000;int MIN[maxn<<2];void PushUP(int rt){    MIN[rt] = min(MIN[rt<<1] , MIN[rt<<1|1]);}void build(int l,int r,int rt){    if (l == r) {       // printf("%d  %d  ",l,rt);  用来观察建树的过程        scanf("%d",&MIN[rt]);        return ;    }    int m = (l + r) >> 1;    build(lson);    build(rson);    PushUP(rt);}int query(int L,int R,int l,int r,int rt){    if (L <= l && r <= R) {        return MIN[rt];    }    int m = (l + r) >> 1;    int ret = 100090;    if (L <= m) ret = min(ret , query(L , R , lson));    if (R > m) ret = min(ret , query(L , R , rson));    return ret;}void update(int p,int sc,int l,int r,int rt) {        //单点替换,本题未用到if (l == r) {MIN[rt] = sc;return ;}int m = (l + r) >> 1;if (p <= m) update(p , sc , lson);else update(p , sc , rson);PushUP(rt);}int main(){    int n , m;    int casesNum;    scanf("%d",&casesNum);    for(int t=1; t<=casesNum; t++) {        scanf("%d%d",&n,&m);        build(1 , n , 1);        printf("Case %d:\n",t);        while (m --) {            int a , b;            scanf("%d %d",&a,&b);            printf("%d\n",query(a , b , 1 , n , 1));        }    }    return 0;}