• [模板] 线段树


    同 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
    ", ask(1, x, y));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    LeetCode——Basic Calculator
    LeetCode——Sqrt(x)
    LeetCode——Binary Search Tree Iterator
    LeetCode——Search for a Range
    LeetCode——pow(x, n)
    LeetCode——Single Number II
    LeetCode——Summary Ranges
    LeetCode——Largest Number
    LeetCode——Kth Largest Element in an Array
    LeetCode——Implement Stack using Queues
  • 原文地址:https://www.cnblogs.com/Foggy-Forest/p/13051459.html
Copyright © 2020-2023  润新知