zoukankan      html  css  js  c++  java
  • 线段树 功能:update:单点替换 query:区间最值 hdu1754

    hud 1754   http://acm.hdu.edu.cn/showproblem.php?pid=1754

    (0)定义

    #include <cstdio>
    #include <algorithm>

    using namespace std;

    const int maxn =222222;
    int MAX[maxn<<2]; //  maxn *4;

    (1) 建立线段树

    void PushUp(int rt) //  rt :当前节点的编号 
    {                    //更新该节点的数据 ,这里是求该节点的最大值 
        MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);    //  <<1==*2 ,<<1|1==*2+1;
    }
    void build(int l,int r,int rt)//建树 ,[l.r]当前节点的区间,rt :当前的节点 
    {
        if(r==l){        //到达子叶节点,
            scanf("%d",&MAX[rt]);     
            return ; 
        } 
        int m=(l+r)>>1;  //  除以2
        //左右递归 
        build(l,m,rt<<1);     
        build(m+1,r,rt<<1|1); 
        
        PushUp(rt); //更新信息 
    }

    (2)单点替换

    void update(int p,int sc,int l,int r,int rt){
        //     P:替换第几个,sc:更换的数据   在[l.r]中查找 
             if(l==r){
                 MAX[rt]=sc;
                 return ;
             }
        int m=(l+r)>>1;
        //判断 p 左还是右 
        if(p<=m){
            update(p,sc,l,m,rt<<1);
        }else{
            update(p,sc,m+1,r,rt<<1|1);
        }
        PushUp(rt);// 子叶替换后 当前节点更新 
    }

    (3) 区间最大值

    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 ret=0;
        if(L<=m)ret=max(ret,query(L,R,l,m,rt<<1));
        if(m<R)ret=max(ret,query(L,R,m+1,r,rt<<1|1));
        return ret;    
    } 

    线段树,不会的话可以多画画自己理解理解;

    附上全部代码

    #include<iostream>
    #include <cstdio>  
    #include <algorithm>
    using namespace std;
    
    const int maxn =222222;
    int MAX[maxn<<2]; //  maxn *4;
    
    
    void PushUp(int rt) //  rt :当前节点的编号 
    {                    //更新该节点的数据 ,这里是求该节点的最大值 
        MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);    //  <<1==*2 ,<<1|1==*2+1;
    }
    void build(int l,int r,int rt)//建树 ,[l.r]当前节点的区间,rt :当前的节点 
    {
        if(r==l){        //到达子叶节点,
            scanf("%d",&MAX[rt]);     
            return ; 
        } 
        int m=(l+r)>>1;  //  除以2
        //左右递归 
        build(l,m,rt<<1);     
        build(m+1,r,rt<<1|1); 
        
        PushUp(rt); //更新信息 
    }
    
    //单点替换 
    void update(int p,int sc,int l,int r,int rt){
        //     P:替换第几个,sc:更换的数据   在[l.r]中查找 
             if(l==r){
                 MAX[rt]=sc;
                 return ;
             }
        int m=(l+r)>>1;
        //判断 p 左还是右 
        if(p<=m){
            update(p,sc,l,m,rt<<1);
        }else{
            update(p,sc,m+1,r,rt<<1|1);
        }
        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 ret=0;
        if(L<=m)ret=max(ret,query(L,R,l,m,rt<<1));
        if(m<R)ret=max(ret,query(L,R,m+1,r,rt<<1|1));
        return ret;    
    } 
    int main(){
        int n,m;
        while(~scanf("%d%d",&n,&m)){
            build(1,n,1);//  建树 从 1 到 n ,当前节点为1 
             while(m--){
                 char op[2];
                 int a,b;
                 scanf("%s%d%d",op,&a,&b);
                 if(op[0]=='Q'){
                     int k=query(a,b,1,n,1);
                     printf("%d
    ",k);
                     //cout<<k<<endl;
                 }
                 else
                 update(a,b,1,n,1);
             } 
            
        }
        return 0;
    } 

    参考至博客 

    https://blog.csdn.net/weizhuwyzc000/article/details/50407450

  • 相关阅读:
    POJ 2260
    安防监控 —— 数据上行刷新与命令下发过程
    安防监控 —— 主框架搭建
    安防监控 —— 软硬件环境分析与通信协议制定
    安防监控项目 —— 需求分析
    安防监控项目 —— 环境搭建
    Linux下I2C总线驱动框架
    IIC总线硬件工作原理(待完善)
    linux驱动面试(转)
    驱动开发 —— 输入子系统(工作逻辑分析)
  • 原文地址:https://www.cnblogs.com/Lsummer-/p/8646518.html
Copyright © 2011-2022 走看看