首页 > 其他 > 详细

线段树模板

时间:2019-08-16 13:37:47      阅读:65      评论:0      收藏:0      [点我收藏+]
技术分享图片
#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;
}
View Code

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

线段树模板

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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!