zoukankan      html  css  js  c++  java
  • [模板] 线段树

    同 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;
    }
    
  • 相关阅读:
    C#获取IP信息
    获取百度地图按条件查找的信息
    react中如何实现一个按钮的动态隐藏和显示(有效和失效)
    es6 关于map和for of的区别有哪些?
    js 高级程序设计 第四章学习笔记
    ant design Table合并单元格合并单元格怎么用?
    React中如何实现模态框每次打开都是初始界面
    前端界面布局相关整理之2017
    待改善的代码整理
    cq三期备注说明
  • 原文地址:https://www.cnblogs.com/Foggy-Forest/p/13051459.html
Copyright © 2011-2022 走看看