【模板】线段树


int val[MAXN];


struct tree
{
  int maxx,sum;
  int add;
  tree()
  {maxx=sum=add=0;}
}use[MAXN*4];

//[ lc(x); rc(x); ]
inline int lc(int x){ return x << 1;}
inline int rc(int x){ return x << 1 | 1;}

//[ up(x); ]
inline void up(int x)
{
  int l=lc(x),r=rc(x);
  use[x].maxx=max(use[l].maxx,use[r].maxx);
  use[x].sum=use[l].sum+use[r].sum;    
}

//[ down(x); ]
//inline max_down(int x)
{
  if(use[x].add!=0)
  {
    int l=lc(x),r=rc(x);
    use[l].maxx+=use[x].add;
    use[r].maxx+=use[x].add;
    use[l].add+=use[x].add;
    use[r].add+=use[x].add;
    use[x].add=0;   
  }       
}

//[ down(x,r-l+1); ]
inline sum_down(int x,int len)
{
 //len=r-l+1
  if(use[x].add!=0)
  {
    int l=lc(x),r=rc(x);
    use[l].sum+=use[x].add*(len-(len>>1));
    use[r].sum+=use[x].add*(len>>1);
    use[l].add+=use[x].add;
    use[r].add+=use[x].add;
    use[x].add=0;   
  }        
}
//[ build(1,1,n); ]</span>
void build(int x,int l,int r)
{
  if(l==r)
  {
    use[x].maxx=use[x].sum=val[l];
    return ;
  }     
  int mid=(l+r)>>1;
  build(lc(x),l,mid);
  build(rc(x),mid+1,r);
  up(x);
}

//[ updata(1,1,n,l,r,v); ]
void updata(int x,int l,int r,int op,int ed,int v)
{
  if(op<=l&&r<=ed)
  {
    use[x].sum+=v*(r-l+1);
    use[x].maxx+=v;
    use[x].add+=v;
    return ;                
  }      
  down(x);     //根据情况选择函数和参数(max or sum)</span></span>
  int mid=(l+r)>>1;
  if(ed<=m)updata(lc(x),l,mid,op,ed,v);
  else if(op>mid)updata(rc(x),mid+1,r,op,ed,v);
  else 
  {
    updata(lc(x),l,mid,op,ed,v);
    updata(rc(x),mid+1,r,op,ed,v);
  }
  up(x);
}
<span style="font-size:18px;color:#FF0000;">[ query(1,1,n,l,r); ]
<span style="color:#993399;">int query(int x,int l,int r,int op,int ed)
{
  if(op<=l&&r<=ed)
  {
   //max:
      return use[x].maxx;
   //sum:
      return use[x].sum;                
  }    
  down(x);      //根据情况选择函数和参数(max or sum)
  int mid=(l+r)>>1;
  if(ed<=mid)return query(lc(x),l,mid,op,ed);
  else if(op>mid)return query(rc(x),mid+1,r,op,ed);
  else
  {
   //max:
      return max( query(lc(x),l,mid,op,ed) , query(rc(x),mid+1,r,op,ed) );
   //sum:
      return query(lc(x),l,mid,op,ed) + query(rc(x),mid+1,r,op,ed);    
  } 
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值