码迷,mamicode.com
首页 > 其他好文 > 详细

【模板】线段树(luogu P3372)

时间:2019-05-29 13:04:00      阅读:98      评论:0      收藏:0      [点我收藏+]

标签:push   bsp   lazy   return   modify   tag   query   type   运算   

#include <cstdio>
#define N 1000010
typedef long long ll;

ll n, m, opt, p, q, s;
ll a[N], add[N << 2], sum[N << 2];

void build(ll i, ll l, ll r){    //建树
    if(l == r){
        sum[i] = a[l];
        return;
    }
ll mid
= (l + r) >> 1; build(i << 1, l, mid); build(i << 1 | 1, mid + 1, r);
sum[i]
= sum[i << 1] + sum[i << 1 | 1]; } void plu(ll i, ll l, ll r, ll v){  //加法运算 add[i] += v; sum[i] += (r - l + 1) * v; } void pushdown(ll i, ll l, ll r, ll mid){  //维护 Lazy-tag if(add[i] == 0) return;
plu(i
<< 1, l, mid, add[i]);
plu(i
<< 1 | 1, mid + 1, r, add[i]);
add[i]
= 0; } ll query(ll i, ll l, ll r, ll x, ll y){   //询问区间和 if(l >= x && r <= y) return sum[i];
ll mid
= (l + r) >> 1, ans = 0; pushdown(i, l, r, mid);
if(x <= mid) ans += query(i << 1, l, mid, x, y); if(y > mid) ans += query(i << 1 | 1, mid + 1, r, x, y);
return ans; } void modify(ll i, ll l, ll r, ll x, ll y, ll v){  //更新区间 if(l >= x && r <= y){ plu(i, l, r, v); return; }
ll mid
= (l + r) >> 1; pushdown(i, l, r, mid);
if(x <= mid) modify(i << 1, l, mid, x, y, v); if(y > mid) modify(i << 1 | 1, mid + 1, r, x, y, v);
sum[i]
= sum[i << 1] + sum[i << 1 | 1]; } int main(){
scanf(
"%lld%lld", &n, &m); for(ll i=1; i<=n; i++) scanf("%lld", &a[i]); build(1, 1, n);
while(m--){ scanf("%lld", &opt);
if(opt == 1){ scanf("%lld%lld%lld", &p, &q, &s); modify(1, 1, n, p, q, s); }
else{ scanf("%lld%lld", &p, &q); printf("%lld\n", query(1, 1, n, p, q)); } } return 0; }

 

【模板】线段树(luogu P3372)

标签:push   bsp   lazy   return   modify   tag   query   type   运算   

原文地址:https://www.cnblogs.com/zengpeichen/p/10943152.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!