HDU1754

线段树

#include<stdio.h>
#include<string.h>
#define MAXN 200005
struct ST //存储类型
{
    int l,r,max; //max表示当前节点的最大值
}st[4*MAXN];
inline int max(int a,int b)
{
	return a>b?a:b;
}
void build(int ll,int rr,int n) //初始化建立线段树
{
    st[n].l=ll;   //表示当前节点的最左端,
    st[n].r=rr;   //表示当前节点的最右端,
    st[n].max=0;  //当前节点的值,初始化全为零,
    if (ll==rr) return ; //如果遇到了根节点
    int mid=(ll+rr)/2;   //将当前节点分开,mid为左孩子的右端点,为右孩子的左端点;
    build(ll,mid,2*n);  //先遍历左边的树
    build(mid+1,rr,2*n+1); //再遍历右边的树
}
void insert(int ll,int rr,int a,int n)  // 更新
{
    if (st[n].l==ll&&st[n].r==rr)
        {st[n].max=a;return ;}//如果找到,就赋值,退出。
    else if (a>st[n].max)
        st[n].max=a; //从新更新;
    int mid=(st[n].l+st[n].r)/2;
    if (rr<=mid) //如果右端点比他的中间区分值mid还小,那么久插到左边,
        insert(ll,rr,a,2*n);
	else if (ll>=mid+1)   //如果左端点比他的中间区分值mid还大,那么久插到右边,
     insert(ll,rr,a,2*n+1);
}
int find(int ll,int rr,int n)   // 查询
{
    if (st[n].l==ll&&st[n].r==rr)
        return st[n].max;     //返回max;
    int mid=(st[n].l+st[n].r)/2;
    if (rr<=mid)         //如果rr小于中点分解值,那么就查找左孩子,
     find(ll,rr,2*n);
	else if (ll>=mid+1) //如果rr大于于中点分解值,那么就查找右孩子,
        find(ll,rr,2*n+1);
    else
    return max(find(ll,mid,2*n),find(mid+1,rr,2*n+1));
}
int main()
{
    int n,m,a,b,i;
    char op;
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        build(1,n,1);
        for (i=1;i<=n;++i)
        {
            scanf("%d",&a);
            insert(i,i,a,1);
        }
        getchar();
        for (i=1;i<=m;++i)
        {
            scanf("%c %d %d",&op,&a,&b);
			getchar();
            if (op=='Q') printf("%d\n",find(a,b,1));
            if (op=='U') insert(a,a,b,1);
        }
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值