hdu_1754 I Hate It

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754

分析:简单线段树,更新点的最大值,随后更新上层区间的最值;找区间的最大值。

我的代码:

#include<stdio.h>
#define MAXN 200005
#define N 5005
int n,m;
struct Node
{
    int l,r;
    int max;
}segTree[4*MAXN];
int p[MAXN];
int Max(int a,int b)
{
    return a>b?a:b;
}
void CreatsegTree(int index,int lef,int rig)  //创建[lef,rig]的线段树。
{
    segTree[index].l =lef;  //一开始居然忘了写这个QAQ;
    segTree[index].r=rig;   //一开始居然忘了写这个QAQ;
    if(segTree[index].l == segTree[index].r)
    {
        segTree[index].max=p[lef];
        return ;
    }
    int mid=(lef+rig)>>1;
    CreatsegTree(index<<1, lef,mid);
    CreatsegTree(index<<1|1 ,mid+1,rig);  //index<<1|1 等价于 index*2+1
    segTree[index].max=Max(segTree[index<<1].max,segTree[index<<1|1].max);
}
void ModifyTree(int index,int k,int M) //找到[k,k],并更新此处的最大值为M。
{  
    // 当segTree[index].l==segTree[index].r 时要就返回。不然会一直我下搜。
    if(segTree[index].l==segTree[index].r)
    {
        //找到[k,k]了,更新此处的最大值为M。
        if(segTree[index].l==k) segTree[index].max=M; 
        return ;
    }
    int mid=(segTree[index].l+segTree[index].r)>>1;
    if(k<=mid)
    {
        ModifyTree( index<<1,k,M);
        //返回时,更新上层的最大值。
        segTree[index].max=Max(segTree[index<<1].max,segTree[index<<1|1].max); 
    }
    else
    {
        ModifyTree( index<<1|1,k,M);
        segTree[index].max=Max(segTree[index<<1].max,segTree[index<<1|1].max);
    }
}
//int ans;
int Query(int index,int a,int b)  //找到[a,b]中的最大值。
{
   // if(ans>segTree[index].max) return -1;
    if(segTree[index].l==a&&segTree[index].r==b)
    {
   //     ans=segTree[index].max;
        return segTree[index].max;
    }
    if(segTree[index].l==segTree[index].r)
    {
        return -1;
    }
    int mid=(segTree[index].l+segTree[index].r)>>1;
    if(b<=mid) Query( index<<1,a,b);
    else if(a>mid) Query( index<<1|1,a,b);
    else
    {
      //  return ans=Max(Query(index<<1,a,mid),Query( index<<1|1,mid+1,b));
      return Max(Query(index<<1,a,mid),Query( index<<1|1,mid+1,b));
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        int i;
        for(i=1;i<=n;i++) scanf("%d",p+i);
        CreatsegTree(1,1,n);
        for(i=0;i<m;i++)
        {
            char str[5];
            scanf("%s",str);
            int a,b;
            scanf("%d%d",&a,&b);
//            ans=0;
            switch(str[0])
            {
                case 'U':ModifyTree(1,a,b);break;
                case 'Q': printf("%d\n",Query(1, a, b));break;
//                    Query(1, a, b);
//                    printf("%d\n",ans);break;
            }
        }
    }

    return 0;
}

总结:线段树代码的细节打的时候要仔细o(>﹏<)o

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值