[模板] 线段树

同 Luogu P3373

注意如果写 pushup 的话不要越界
注意更新 sum 值的位置

# include <iostream>
# include <cstdio>
# define MAXN 100000+5
# define LL long long

using namespace std;

struct node{
    int l, r;
    int lazyA;
    LL sum;
}a[MAXN<<2];

int lim;

void pushdown(int now){
    if(a[now].lazyA){
        a[now<<1].sum += (a[now<<1].r - a[now<<1].l + 1) * a[now].lazyA;
        a[now<<1|1].sum += (a[now<<1|1].r - a[now<<1|1].l + 1) * a[now].lazyA;
        a[now<<1].lazyA += a[now].lazyA, a[now<<1|1].lazyA += a[now].lazyA;
        a[now].lazyA = 0; 
    }
    return;
}

void build(int now, int l, int r){
    a[now].l = l, a[now].r = r;

    if(l == r){
        scanf("%lld", &a[now].sum);
        return;
    }

    int mid = ( l + r ) >> 1;
    build(now<<1, l, mid);
    build(now<<1|1, mid+1, r);
    a[now].sum = a[now<<1].sum + a[now<<1|1].sum;
    return;
}

void add(int now, int l, int r, LL val){
    if(a[now].l >= l && a[now].r <= r){
        a[now].sum += val * (a[now].r - a[now].l + 1);
        a[now].lazyA  += val; // 当前节点的区间被完全覆盖的情况
        return;
    }
    pushdown(now);

    int mid = (a[now].l + a[now].r) >> 1;
    if(l <= mid) add(now<<1, l, r, val);
    if(r > mid) add(now<<1|1, l, r, val);
    // 因为上面的限定是完全覆盖所以 l r 打法不会出问题
    a[now].sum = a[now<<1].sum + a[now<<1|1].sum;
    return;
}

LL ask(int now, int l, int r){
    if(a[now].l >= l && a[now].r <= r)
        return a[now].sum;
    pushdown(now);

    LL sum = 0;
    int mid = (a[now].l + a[now].r) >> 1;
    if(l <= mid) sum += ask(now<<1, l, r);
    if(r > mid) sum += ask(now<<1|1, l, r);
    return sum;
}

int main(){
    int n, m, opt, x, y, k;
    scanf("%d%d", &n, &m);
    build(1, 1, n);
    for(int i = 1; i <= m; i++){
        scanf("%d", &opt);
        if(opt == 1){
            scanf("%d%d%d", &x, &y, &k);
            add(1, x, y, k);
        }
        else{
            scanf("%d%d", &x, &y);
            printf("%lld\n", ask(1, x, y));
        }
    }
    return 0;
}

原文链接: https://www.cnblogs.com/Foggy-Forest/p/13051459.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    [模板] 线段树

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/353155

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午7:54
下一篇 2023年3月2日 上午7:55

相关推荐