[Template] segment tree (luogu P3372)

#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; }

 

Guess you like

Origin www.cnblogs.com/zengpeichen/p/10943152.html