线段树模板
#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\n", query( 1, 1, n, l, r ) ); } } } return 0; }
没有记住push_down的位置以及lazytag 其实是 用于 下放变量 之前的