线段树(区间更新)


#include <iostream>
#include <cstdio>
using namespace std;

typedef long long ll;

ll a[100005];
struct node 
{
  int l, r;
  ll  sum, lazy;
}tree[500005];
int n;

void Updown(int rt)              //更新区间的值
{
  tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
}

void Pushdown(int rt)
{
  if(tree[rt].lazy)
  {
    tree[rt << 1].lazy += tree[rt].lazy;
    tree[rt << 1 | 1].lazy += tree[rt].lazy;
    tree[rt << 1].sum += tree[rt].lazy * (tree[rt << 1].r - tree[rt].l + 1);
    tree[rt << 1 | 1].sum += tree[rt].lazy * (tree[rt << 1 | 1].r - tree[rt << 1 | 1].l + 1);
    tree[rt].lazy = 0;
  }
}

void Build(int l, int r, int rt)       ///建线段树
{
  tree[rt].l = l;
  tree[rt].r = r;
  tree[rt].sum = 0;
  tree[rt].lazy = 0;
  if(l == r)
  {
    tree[rt].sum = a[l];
    return;
  }
  int mid = (l + r) / 2;
  Build(l, mid, rt << 1);
  Build(mid + 1, r, rt << 1 | 1);
  Updown(rt);
} 

ll Query(int l, int r, int rt)         ///询问区间的值
{
  if(tree[rt].l == l && tree[rt].r == r)
  {
    return tree[rt].sum;
  }
  Pushdown(rt);
  int mid = (tree[rt].l + tree[rt].r) / 2;
  ll ans = 0;
  if(mid >= r)
   ans += Query(l, r, rt << 1);
  else if(mid < l)
    ans += Query(l, r, rt << 1 | 1);
  else 
  {
    ans += Query(l, mid, rt << 1);
    ans += Query(mid + 1, r, rt << 1 | 1);
  }
  return ans;
}

void Update(int l, int r, int val, int rt)
{
  if(tree[rt].l == l && tree[rt].r == r)
  {
     tree[rt].lazy += val;
     tree[rt].sum += val * (tree[rt].r - tree[rt].l + 1);
     return;
  }
  Pushdown(rt);
  int mid = (tree[rt].r + tree[rt].l) / 2;
  if(mid >= r)
    Update(l, r, val, rt << 1);
  else if(mid < l)
    Update(l, r, val, rt << 1 | 1);
  else 
  {
    Update(l, mid, val, rt << 1);
    Update(mid + 1, r, val, rt << 1 | 1);
  }
  Updown(rt);
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值