• 链接 | zkw线段树


    [数据结构]走近Zkw线段树(一)

    [数据结构]走近Zkw线段树(二)

    线段树的扩展之浅谈zkw线段树

    #include<bits/stdc++.h>
    #define lc(x) (x<<1)
    #define rc(x) (x<<1|1)
    using namespace std;
    const int maxn = 100005;
    int max(int a, int b) { return a>b ? a : b; }
    
    long long tr[maxn<<2];
    int M, N;
    
    void maintain(int p) { tr[p] = tr[lc(p)] + tr[rc(p)]; }
    
    void build() {
        for(M=1; M<=N; M++);
        for(int i=M+1; i<=M+N; i++) scanf("%lld", &tr[i]);
        for(int i=M-1; i; i--) maintain(i);
    }
    
    void single_update(int pos, int v) {
        pos += M;
        tr[pos] += v;
        for(pos>>=1; pos; pos>>=1) maintain(pos);
    }
    
    long long static_RMQ(int l, int r) {
        long long ans=0;
        for(l+=M-1,r+=M+1; l^r^1; l>>=1, r>>=1) {
            if(!(l&1)) ans += tr[l^1];
            if(r&1) ans += tr[r^1];
        }
        return ans;
    }
    
    int main() {
        int m;
        scanf("%d%d", &N, &m);
        build();
        while(m--) {
            int op, i, j;
            scanf("%d%d%d", &op, &i, &j);
            if(op == 1) update(i, j);
            else printf("%lld
    ", RMQ(i, j));
        }
        return 0;
    }
    单点更新

    -

    #include<bits/stdc++.h>
    #define lc(x) (x<<1)
    #define rc(x) (x<<1|1)
    using namespace std;
    const int maxn = 100005, maxm = maxn<<2;
    typedef long long LL;
    int max(int a, int b) { return a>b ? a : b; }
    
    LL tr[maxm];
    int M, N;
    int L[maxm], R[maxm];
    LL down[maxm];
    
    void maintain(int p) { tr[p] = tr[lc(p)] + tr[rc(p)]; }
    
    void build() {
        for(M=1; M<=N; M++);
        for(int i=M+1; i<=M+N; i++) {
            scanf("%lld", &tr[i]);
            L[i] = R[i] = i-M;
        }
        for(int i=M-1; i; i--) {
            maintain(i);
            L[i] = L[lc(i)];
            R[i] = R[rc(i)];
        }
    }
    
    //区间和式pushDown 
    void pushDown(int p) {
        if(down[p] && p<M) { // 不是叶节点 
            down[lc(p)] += down[p]; down[rc(p)] += down[p];
            tr[lc(p)] += (R[lc(p)] - L[lc(p)] + 1) * down[p];
            tr[rc(p)] += (R[rc(p)] - L[rc(p)] + 1) * down[p];
            down[p] = 0;
        }
    }
    
    //从叶节点往回走到根,再自顶向下下推标记 
    void applyTag(int p) {
        stack<int> s;
        while(p) s.push(p), p>>=1;
        while(!s.empty()) pushDown(s.top()), s.pop();
    }
    
    void range_update(int l, int r, int v) {
        bool vl, vr; vl = vr = false;
        int x;
        int sl=0, sr=0;
        for(l += M-1, r += M+1; l^r^1; l>>=1, r>>=1) {
            if(~l&1) {
                x = l^1; // 点l^1被完整包含在更新的区间里 
                if(!vl) {
                    sl = x; // 记录最底层被完整包含的区间 
                    applyTag(x), vl = true;
                }
                down[x] += v;
                tr[x] += (R[x] - L[x] + 1) * v;
            }
            if(r&1) {
                x = r^1; // 点r^1同理 
                if(!vr) {
                    sr = x;
                    applyTag(x), vr = true;
                }
                down[x] += v;
                tr[x] += (R[x] - L[x] + 1) * v;
            }
        }
        for(sl>>=1; sl; sl>>=1) maintain(sl); //从最底层被完整包含的区间向上更新维护 
        for(sr>>=1; sr; sr>>=1) maintain(sr);
    }
    
    LL range_query(int l, int r) {
        bool vl, vr; vl = vr = false;
        LL ans=0;
        for(l += M-1, r += M+1; l^r^1; l>>=1, r>>=1) {
            if(~l&1) {
                if(!vl) applyTag(l^1), vl = true;
                ans += tr[l^1];
            }
            if(r&1) {
                if(!vr) applyTag(r^1), vr = true;
                ans += tr[r^1];
            }
        }
        return ans;
    }
    
    int main() {
        int m;
        scanf("%d%d", &N, &m);
        build();
        while(m--) {
            int op, a, b, v;
            scanf("%d%d%d", &op, &a, &b);
            if(op == 1) scanf("%d", &v), range_update(a, b, v);
            else printf("%lld
    ", range_query(a, b));
        }
        return 0;
    }
    区间和更新

    -

  • 相关阅读:
    sort()的部分用法
    蓝桥杯 算法训练 审美课
    蓝桥杯 基础练习 查找整数
    2018年第九届蓝桥杯【C++省赛B组】【第二题:明码】
    蓝桥杯 特殊回文数
    比较两文本程序
    蓝桥杯 基础练习 十六进制转八进制
    Python | 用Pyinstaller打包发布exe应用
    SpringBoot-04-整合JDBC
    SpringBoot-03-自定义Starter
  • 原文地址:https://www.cnblogs.com/de-compass/p/12054884.html
Copyright © 2020-2023  润新知