线段树模板

1.

    单点更新(add),区间查询

   

void update(int p,int add,int rt,int l,int r)  
{  
    if(p>r) return;  
    if(l==r)  
    {  
        tree[rt].sum+=add;  
        return;  
    }  
    else  
    {  
        int m=(l+r)>>1;  
        if(p<=m) update(p,add,lson);//3. 要p的作用哪。只更新一半 。因为下面有Pushup  
        else update(p,add,rson);  
    }  
    Pushup(rt);  
}  
int query(int a,int b,int rt,int l,int r)  
{  
    int ans=0;  
    if(a<=l&&b>=r)  
    {  
        return tree[rt].sum;  
    }  
    else  
    {  
        int m=(l+r)>>1;  
        if(a<=m)  
            ans+=query(a,b,lson);  
        if(b>m) //4. 这地方是r>m果断而不是r>=m  
            ans+=query(a,b,rson);  
    }  
    return ans;  
}  


2.

     单点更新,区间最值查询

     与1的主要区别就是Max的更新吧。  

void Pushup(int rt)
{
    tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max);
}

void build(int rt,int l,int r)
{
   if(l==r) {scanf("%d",&tree[rt].Max);return;}//1. 这地方一开始忘了return
   else
   {
       int m=(l+r)>>1;
       build(lson);
       build(rson);
   }
   Pushup(rt);
}
void update(int a,int b,int rt,int l,int r)
{
    if(l==r) {tree[rt].Max=b;return;}
    else
    {
        int m=(l+r)>>1;
        if(a<=m) update(a,b,lson);
        if(a>m)  update(a,b,rson);
    }
    Pushup(rt);
}
int query(int a,int b,int rt,int l,int r)
{
    int ans=0;
    if(a<=l&&b>=r) //2. 这地方不留意错写成l==r  return 还是自己不理解。
    {
        return tree[rt].Max;
    }
    else
    {
        int m=(l+r)>>1;
        if(a<=m) ans=max(ans,query(a,b,lson));
        if(b>m) ans=max(ans,query(a,b,rson));
    }
    return ans;
}
原文地址:https://www.cnblogs.com/riskyer/p/3275582.html