线段树模板

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>

const int maxn = 100000 + 1;
typedef long long ll;
ll a[maxn], tree[maxn<<2], tag[maxn<<2];
using namespace std;
#define lc(i) i<<1
#define rc(i) i<<1|1

void push_up ( ll p ) {
    tree[p] = tree[lc(p)] + tree[rc(p)];
}
void Build ( ll i, ll l, ll r ) {
    tag[i] = 0;
    if ( l == r ) {
        tree[i] = a[l];
        return ;
    }
    ll mid = ( l + r )>>1;
    Build ( lc(i), l, mid );
    Build ( rc(i), mid+1, r );
    push_up ( i );
}
void f ( ll i, ll l, ll r, ll k ) {
    tree[i] += k * ( r - l + 1 );
    tag[i] += k;
}
void push_down ( ll i, ll l, ll r ) {
    ll mid = ( l + r ) >> 1;
    f ( lc(i), l, mid, tag[i] );
    f ( rc(i), mid+1, r, tag[i]);
    tag[i] = 0;
}

void update ( ll i, ll l, ll r, ll lu, ll ru, ll k ) {
    if ( l == lu && r == ru ) {
        f ( i, l, r, k );
        return;
    }
    push_down ( i, l, r );
    ll mid = ( l + r )>>1;
    if ( mid < lu ) {
        update ( rc(i), mid+1, r, lu, ru, k );
    } else if ( ru <= mid ) {
        update ( lc(i), l, mid, lu, ru, k );
    } else {
        update (lc(i), l, mid, lu, mid, k );
        update (rc(i), mid+1, r, mid+1, ru, k );
    }
    push_up ( i );
}
ll query ( ll i, ll l, ll r, ll lq, ll rq ) {
    if ( l == lq && rq == r ) {
        return tree[i];
    }
    push_down ( i, l, r );
    ll res = 0, mid = (l + r)>>1;
    if ( rq <= mid ) {
        res = query ( lc(i), l, mid, lq, rq);
    } else if ( lq > mid ) {
        res = query ( rc(i), mid+1, r, lq, rq);
    } else {
        res += query ( lc(i), l, mid, lq, mid);
        res += query ( rc(i), mid+1, r, mid+1, rq);
    }
    
    return res;
}
int main () {
    ll n, m;
    while ( scanf("%lld%lld", &n, &m) != EOF ) {
        ll l, r, k;

        for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
        Build (1, 1, n);
        while (m--) {
            int fl;
            scanf("%d", &fl);
            if (fl == 1) {
                scanf("%lld%lld%lld", &l, &r, &k);
                update ( 1, 1, n, l, r, k );
            } else {
                scanf("%lld%lld", &l, &r);
                printf("%lld
", query( 1, 1, n, l, r ) );
            }
        }
    }
    return 0;
}
View Code

没有记住push_down的位置以及lazytag 其实是 用于 下放变量 之前的

原文地址:https://www.cnblogs.com/Urchin-C/p/11362726.html