线段树区间求最大值

/** \brief
 *  求线段树某个区间的最大值
 */


#include <stdio.h>


int max[100];


void Build(int lift, int right, int rt);
void updata(int point, int x, int lift, int right, int rt);
int query(int L, int R, int lift, int right, int rt);


int main()
{
    int lift, right;
    printf("输入你要构建的范围: ");
    scanf("%d%d", &lift, &right);
    Build(lift, right, 1);


    int point, x;
    printf("请输入你要更新的点和更新的数: ");
    scanf("%d%d", &point, &x);
    updata(point, x, lift, right, 1);


    int L, R;
    printf("请输入你要查找的区间: ");
    scanf("%d%d", &L, &R);
    printf("%d\n", query(L, R, lift, right, 1));


    return 0;
}


void Build(int lift, int right, int rt)
{
    if (lift == right) {
        scanf("%d", &max[rt]);
        return ;
    }


    int m = (lift + right) / 2;
    Build(lift, m, rt*2);      // 构建左儿子
    Build(m+1, right, rt*2+1); // 构建右儿子


    max[rt] = max[rt*2] > max[rt*2+1] ? max[rt*2]: max[rt*2+1];
}


// 实现单点替换为 x; 替换的点为 point;
void updata(int point, int x, int lift, int right, int rt)
{
    if (lift == right) {
        max[rt] = x;
        return ;
    }


    int m = (lift + right) / 2;
    if (point <= m)
        updata(point, x, lift, m, rt*2); // 向左寻找
    else
        updata(point, x, m+1, right, rt*2+1); // 向右寻找


    // 已经找完之后, 再更新上面的点;


    max[rt] = max[rt*2] > max[rt*2+1] ? max[rt*2]: max[rt*2+1];
}


// 函数返回某个区间段上的最大值;
int query(int L, int R, int lift, int right, int rt)
{
    int Max(int x, int y);


    int ret = 0;
    // 函数的基准: 找到一个完全被 L R包含的范围(且是兄弟子叶——同父亲);
    if (lift >= L && right <= R)
        return max[rt];


    int m = (lift + right) / 2;
    if (L <= m) // 向左传递
        ret = Max(ret, query(L, R, lift, m, rt*2));
    if (R > m)
        ret = Max(ret, query(L, R, m+1, right, rt*2+1));


    return ret;
}


int Max(int x, int y)
{
    return x > y ? x: y;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值