HDU 1754(I Hate It)

本文介绍了一种使用C语言实现的段式树结构,通过具体的代码示例详细讲解了如何构建段式树、进行节点更新及查询最大值的操作。适用于需要高效处理区间查询和更新的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<stdio.h>
#define size 1000100
#define maxNum(a,b) a>b?a:b
typedef struct node
{
    int left,right;
    int max;
};
int num[size],id,maxValue;
node tree[size];
void creat(int left,int right,int no)/**建树*/
{
    int mid=(left+right)/2;
    tree[no].left=left;
    tree[no].right=right;
    if(left==right)/**当区间为单个元素的时候,录入对应的值*/
    {
        tree[no].max=num[id++];
        return ;
    }
    creat(left,mid,no*2);/**递归处理左子树*/
    creat(mid+1,right,no*2+1);/**递归处理右子树*/
    tree[no].max=maxNum(tree[no*2].max,tree[no*2+1].max);/**更新父亲结点*/
}
void update(int no,int idx,int value)/**修改和更新*/
{
    int mid=(tree[no].left+tree[no].right)/2;
    if(tree[no].left==tree[no].right)
    {
        tree[no].max=value;
        return ;
    }
    if(idx>mid)/**如果需更新的结点编号大于当前区间,递归处理右子树*/
        update(no*2+1,idx,value);
    if(idx<=mid)/**继续处理左子树*/
        update(no*2,idx,value);
    tree[no].max=maxNum(tree[no*2].max,tree[no*2+1].max);/**回溯的时候顺便更新下父亲结点*/
}
void query(int left,int right,int no)/**问答函数,原理和更新函数类似*/
{
    int mid=(tree[no].left+tree[no].right)/2;
    if(left<=tree[no].left&&tree[no].right<=right)
    {
        maxValue=maxNum(maxValue,tree[no].max);
        return ;
    }
    if(left<=mid)
        query(left,right,no*2);
    if(right>mid)
        query(left,right,no*2+1);
    
}
int main()
{
    char order;
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        int i,a,b;
        maxValue=-1;
        id=0;
        for(i=0;i<n;i++)
            scanf("%d",&num[i]);
        creat(1,n,1);/**建树的时候从区间1-N(即总区间)开始往下*/
        for(i=0;i<m;i++)
        {
            scanf("\n%c%d%d",&order,&a,&b);
            if(order=='U')
                update(1,a,b);/**插入和更新下标从1(即最顶层的结点)开始往下*/
            if(order=='Q')
            {
                query(a,b,1);
                printf("%d\n",maxValue);
                maxValue=-1;
            }
        }        
    }
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值