zoukankan      html  css  js  c++  java
  • hdu1754简单线段树,点修改,区间最值

    链接:http://www.cnblogs.com/54zyq/p/3222818.html

    题意:中文题~

    思路:线段树点修改,求区间中的最大值。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    const int maxn=200000+5;
    int MAX[maxn<<2];
    void PushUP(int rt)
    {
        MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
    }
    void build(int l,int r,int rt)
    {//(l,r)为题目要求的总区间,rt为第一个点
        if(l==r)
        {
            scanf("%d",&MAX[rt]);
            return;
        }
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        PushUP(rt);
    }
    void update(int p,int s,int l,int r,int rt)
    {
        if(l==r)
        {
            MAX[rt]=s;
            return;
        }
        int m=(l+r)>>1;
        if(p<=m) update(p,s,lson);
        else update(p,s,rson);
        PushUP(rt);//每次修改一个点后这一段的最大值可能会变化,所以必须更新
    }
    int query(int L,int R,int l,int r,int rt)
    {//[L,R]要查询的区间,在一次查询过程中不会改变,[l,r]当前节点对应的区间,每次递归这个区间就变化一次
    
        if(L<=l && r<=R)//当前节点对应的区间完全包含在查询区间内
            return MAX[rt];
        int m=(l+r)>>1;
        int ans=0;
        if(L<=m) ans=max(ans,query(L,R,lson));
        if(R>m) ans=max(ans,query(L,R,rson));//递归比较大小
        return ans;
    }
    int main()
    {
    //    freopen("hdu.cpp","r",stdin);
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            build(1,n,1);//建树
            while(m--)
            {
                char op[2];
                int a,b;
                scanf("%s%d%d",op,&a,&b);
                if(op[0]=='Q')
                   printf("%d
    ",query(a,b,1,n,1));
                else update(a,b,1,n,1);
            }
        }
        return 0;
    }

    前一段时间也看了一下线段树,似懂非懂,认识不深,现在再来学习后,有了新的感觉。

  • 相关阅读:
    C语言学习代码〈二〉
    C语言学习笔记<三 >
    C语言学习笔记<一 >
    C语言学习代码〈四〉
    C语言学习代码〈三〉
    C语言学习笔记<五>
    C语言学习笔记<四>
    C语言学习笔记<二 >
    C语言学习代码<一> .
    周末练习
  • 原文地址:https://www.cnblogs.com/54zyq/p/3266129.html
Copyright © 2011-2022 走看看