线段树 功能: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\n",k);
                 //cout<<k<<endl;
             }
             else
             update(a,b,1,n,1);
         } 
        
    }
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/LSummer_/article/details/80068355