zoukankan      html  css  js  c++  java
  • 线段树 区间更新(加减乘)模板

    #include<bits/stdc++.h>
    using namespace std;
    
    const int MAXN = 500000 + 1;
    const int ADD = 1, MUL = 2;
    
    int n, m, p=1e9+7;
    long long a[MAXN];
    struct node {
        long long sum, addv, mulv;
    }t[MAXN << 2];
    
    inline long long read() {
        long long x = 0, f = 1; char ch = getchar();
        while(ch < '0' || ch > '9') {
            if(ch == '-') f = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
            x = (x << 3) + (x << 1) + ch - 48, ch = getchar();
        return x * f;
    }
    
    void Build(int o, int l, int r) {
        t[o].mulv = 1;
        if(l == r) t[o].sum = a[l];
        else {
            int mid = (l + r) >> 1;
            Build(o << 1, l, mid);
            Build(o << 1|1, mid + 1, r);
            t[o].sum = (t[o << 1].sum + t[o << 1|1].sum) % p;
        }
    }
    
    inline void down(int o, int len) {
        long long mul = t[o].mulv, add = t[o].addv;
        t[o << 1].sum = (t[o << 1].sum * mul + add * (len - (len >> 1))) % p;
        t[o << 1|1].sum = (t[o << 1|1].sum * mul + add * (len >> 1)) % p;
        t[o << 1].mulv = (t[o << 1].mulv * mul) % p;
        t[o << 1|1].mulv = (t[o << 1|1].mulv * mul) % p;
        t[o << 1].addv = (t[o << 1].addv * mul + add) % p;
        t[o << 1|1].addv = (t[o << 1|1].addv * mul + add) % p;
        t[o].mulv = 1, t[o].addv = 0;
    }
    void Update(int o, int l, int r, int ul, int ur, long long v, int fl) {
        if(ul <= l && r <= ur) {
            if(fl == 1) {
                t[o].sum = (t[o].sum + v * (r - l + 1)) % p;
                t[o].addv = (t[o].addv + v) % p;
            }
            else if(fl == 2) {
                t[o].sum = (t[o].sum * v) % p;
                t[o].mulv = (t[o].mulv * v) % p;
                t[o].addv = (t[o].addv * v) % p;
            }
        }
        else {
            if(t[o].mulv != 1 || t[o].addv)
                down(o, r - l + 1);
            int mid = (l + r) >> 1;
            if(ul <= mid) Update(o << 1, l, mid, ul, ur, v, fl);
            if(ur > mid) Update(o << 1|1, mid + 1, r, ul, ur, v, fl);
            t[o].sum = (t[o << 1].sum + t[o << 1|1].sum) % p;
        }
    }
    
    long long Query(int o, int l, int r, int ql, int qr) {
        if(ql <= l && r <= qr) return t[o].sum % p;
        int mid = (l + r) >> 1;
        long long ret = 0;
        if(t[o].mulv != 1 || t[o].addv)
            down(o, r - l + 1);
        if(ql <= mid) ret += Query(o << 1, l, mid, ql, qr);
        if(qr > mid) ret += Query(o << 1|1, mid + 1, r, ql, qr);
        return ret % p;
    }
    
    int main()
    {
        n = read(), m = read();
        for(int i=1; i<=n; ++i)
            a[i] = read();
        Build(1, 1, n);
        while(m--) {
            char s[10];
            scanf("%s",s);
            long long  x = read(), y = read();
            if(s[0] == 'M') {
                long long k = read();
                Update(1, 1, n, x, y, k, MUL);
            }
            else if(s[0] == 'A') {
                long long k = read();
                Update(1, 1, n, x, y, k, ADD);
            }
            else if(s[0] == 'S') {
                long long k = read();
                Update(1, 1, n, x, y, k*-1, ADD);
            }
            else if(s[0] =='Q') printf("%lld
    ", Query(1, 1, n, x, y));
        }
        return 0;
    }
    /*
    5 6
    1 1 1 1 1
    A 1 3 6
    S 2 3 3
    Q 1 3
    M 1 5 6
    Q 1 5
    Q 2 3
    */
    
  • 相关阅读:
    Tomcat 调优的技巧
    双亲委派模型
    字典树实现
    Python获取房价信息和导出EXCEL
    日志检索关键字并截取上下行关联内容
    GC日志分析
    Linux 查看 删除进程
    Rotate partitions in DB2 on z
    C++ STL string
    DB2 for z: system catalog tables
  • 原文地址:https://www.cnblogs.com/weimeiyuer/p/9677445.html
Copyright © 2011-2022 走看看