• 【数据结构】线段树-区间修改


    区间加法

    struct SegmentTree {
    
    #define ls (u << 1)
    #define rs (u << 1 | 1)
    #define mid ((l + r) >> 1)
    
        static const int MAXN = 2e5 + 10;
        static const ll LINF = 1e18 + 10;
    
        ll tag[MAXN << 2];
        ll mi[MAXN << 2];
        ll mx[MAXN << 2];
        ll sum[MAXN << 2];
    
        void PushUp(int u) {
            mi[u] = min(mi[ls], mi[rs]);
            mx[u] = max(mx[ls], mx[rs]);
            sum[u] = sum[ls] + sum[rs];
        }
    
        void PushDown(int u, int l, int r) {
            ll t = tag[u];
            if(t != 0) {
                tag[ls] += t, mi[ls] += t, mx[ls] += t;
                sum[ls] += 1LL * (mid - l + 1) * t;
                tag[rs] += t, mi[rs] += t, mx[rs] += t;
                sum[rs] += 1LL * (r - mid) * t;
                tag[u] = 0;
            }
        }
    
        void Build(int u, int l, int r) {
            tag[u] = 0;
            if(l == r) {
                mi[u] = mx[u] = sum[u] = 0;
                return;
            }
            Build(ls, l, mid);
            Build(rs, mid + 1, r);
            PushUp(u);
        }
    
        void UpdateAdd(int u, int l, int r, int L, int R, ll v) {
            if(L <= l && r <= R) {
                tag[u] += v, mi[u] += v, mx[u] += v;
                sum[u] += 1LL * (r - l + 1) * v;
                return;
            }
            PushDown(u, l, r);
            if(L <= mid) UpdateAdd(ls, l, mid, L, R, v);
            if(R >= mid + 1) UpdateAdd(rs, mid + 1, r, L, R, v);
            PushUp(u);
        }
    
        ll QueryMin(int u, int l, int r, int L, int R) {
            if(L <= l && r <= R)
                return mi[u];
            PushDown(u, l, r);
            ll res = LINF;
            if(L <= mid) res = min(res, QueryMin(ls, l, mid, L, R));
            if(R >= mid + 1) res = min(res, QueryMin(rs, mid + 1, r, L, R));
            return res;
        }
    
        ll QueryMax(int u, int l, int r, int L, int R) {
            if(L <= l && r <= R)
                return mx[u];
            PushDown(u, l, r);
            ll res = -LINF;
            if(L <= mid) res = max(res, QueryMax(ls, l, mid, L, R));
            if(R >= mid + 1) res = max(res, QueryMax(rs, mid + 1, r, L, R));
            return res;
        }
    
        ll QuerySum(int u, int l, int r, int L, int R) {
            if(L <= l && r <= R)
                return sum[u];
            PushDown(u, l, r);
            ll res = 0;
            if(L <= mid) res += QuerySum(ls, l, mid, L, R);
            if(R >= mid + 1) res += QuerySum(rs, mid + 1, r, L, R);
            return res;
        }
    
    #undef ls
    #undef rs
    #undef mid
    
    } st;
    

    区间设值

    struct SegmentTree {
    
    #define ls (u << 1)
    #define rs (u << 1 | 1)
    #define mid ((l + r) >> 1)
    
        static const int MAXN = 2e5 + 10;
        static const ll LINF = 1e18 + 10;
    
        ll tag[MAXN << 2];
        ll mi[MAXN << 2];
        ll mx[MAXN << 2];
        ll sum[MAXN << 2];
    
        void PushUp(int u) {
            mi[u] = min(mi[ls], mi[rs]);
            mx[u] = max(mx[ls], mx[rs]);
            sum[u] = sum[ls] + sum[rs];
        }
    
        void PushDown(int u, int l, int r) {
            ll t = tag[u];
            if(t != LINF) {
                tag[ls] = mi[ls] = mx[ls] = t;
                sum[ls] = 1LL * (mid - l + 1) * t;
                tag[rs] = mi[rs] = mx[rs] = t;
                sum[rs] = 1LL * (r - mid) * t;
                tag[u] = LINF;
            }
        }
    
        void Build(int u, int l, int r) {
            tag[u] = LINF;
            if(l == r) {
                mi[u] = mx[u] = sum[u] = 0;
                return;
            }
            Build(ls, l, mid);
            Build(rs, mid + 1, r);
            PushUp(u);
        }
    
        void UpdateSet(int u, int l, int r, int L, int R, ll v) {
            if(L <= l && r <= R) {
                tag[u] = mi[u] = mx[u] = v;
                sum[u] = 1LL * (r - l + 1) * v;
                return;
            }
            PushDown(u, l, r);
            if(L <= mid) UpdateSet(ls, l, mid, L, R, v);
            if(R >= mid + 1) UpdateSet(rs, mid + 1, r, L, R, v);
            PushUp(u);
        }
    
        ll QueryMin(int u, int l, int r, int L, int R) {
            if(L <= l && r <= R)
                return mi[u];
            PushDown(u, l, r);
            ll res = LINF;
            if(L <= mid) res = min(res, QueryMin(ls, l, mid, L, R));
            if(R >= mid + 1) res = min(res, QueryMin(rs, mid + 1, r, L, R));
            return res;
        }
    
        ll QueryMax(int u, int l, int r, int L, int R) {
            if(L <= l && r <= R)
                return mx[u];
            PushDown(u, l, r);
            ll res = -LINF;
            if(L <= mid) res = max(res, QueryMax(ls, l, mid, L, R));
            if(R >= mid + 1) res = max(res, QueryMax(rs, mid + 1, r, L, R));
            return res;
        }
    
        ll QuerySum(int u, int l, int r, int L, int R) {
            if(L <= l && r <= R)
                return sum[u];
            PushDown(u, l, r);
            ll res = 0;
            if(L <= mid) res += QuerySum(ls, l, mid, L, R);
            if(R >= mid + 1) res += QuerySum(rs, mid + 1, r, L, R);
            return res;
        }
    
    #undef ls
    #undef rs
    #undef mid
    
    } st;
    

    混合标记:
    加法和乘法的混合标记

    超省心版:

    struct SegmentTree {
    
    private:
    
    #define ls (u << 1)
    #define rs (u << 1 | 1)
    #define mid ((l + r) >> 1)
    
        static const int MAXN = 3e5 + 10;
        static const ll LINF = 1e18 + 10;
    
        int n;
        struct Node {
            ll sum, mi, ma;
            ll len, tag;
            Node() {
                sum = 0, mi = 0, ma = 0;
                len = 1, tag = 0;
                return;
            }
            Node& operator=(ll val) {
                sum = 1LL * len * val, mi = val, ma = val;
                tag = 0;
                return *this;
            }
            Node& operator+=(ll val) {
                sum += 1LL * len * val, mi += val, ma += val;
                tag += val;
                return *this;
            }
        } node[MAXN << 2];
    
        Node merge(const Node &x, const Node &y) {
            Node res;
            res.sum = x.sum + y.sum;
            res.mi = min(x.mi, y.mi);
            res.ma = min(x.ma, y.ma);
            res.len = x.len + y.len;
            res.tag = 0;
            return move(res);
        }
    
        void pull(int u) {
            node[u] = merge(node[ls], node[rs]);
            return;
        }
    
        void push(int u) {
            if (node[u].tag != 0) {
                node[ls] += node[u].tag;
                node[rs] += node[u].tag;
                node[u].tag = 0;
            }
            return;
        }
    
        void iBuild(int u, int l, int r) {
            if (l > r)
                return;
            if (l == r) {
                node[u] = Node();
                return;
            }
            iBuild(ls, l, mid);
            iBuild(rs, mid + 1, r);
            pull(u);
            return;
        }
    
        void iUpdate(int u, int l, int r, int lpos, int rpos, ll val) {
            if (l > r || lpos > r || rpos < l)
                return;
            if (lpos <= l && r <= rpos) {
                node[u] += val;
                return;
            }
            push(u);
            iUpdate(ls, l, mid, lpos, rpos, val);
            iUpdate(rs, mid + 1, r, lpos, rpos, val);
            pull(u);
            return;
        }
    
        Node iQuery(int u, int l, int r, int lpos, int rpos) {
            if (l > r || lpos > r || rpos < l)
                return Node();
            if (lpos <= l && r <= rpos)
                return node[u];
            push(u);
            Node resL = iQuery(ls, l, mid, lpos, rpos);
            Node resR = iQuery(rs, mid + 1, r, lpos, rpos);
            return merge(resL, resR);
        }
    
    #undef ls
    #undef rs
    #undef mid
    
    public:
    
        void build(int n) {
            this->n = n;
            iBuild(1, 1, n);
            return;
        }
    
        void update(int lpos, int rpos, ll val) {
            iUpdate(1, 1, n, lpos, rpos, val);
            return;
        }
    
        Node query(int lpos, int rpos) {
            return iQuery(1, 1, n, lpos, rpos);
        }
    
        ll querySum(int lpos, int rpos) {
            return query(lpos, rpos).sum;
        }
    
        ll queryMin(int lpos, int rpos) {
            return query(lpos, rpos).mi;
        }
    
        ll queryMax(int lpos, int rpos) {
            return query(lpos, rpos).ma;
        }
    
    } st;
    
  • 相关阅读:
    [转载]centos 6.4中git如何正常显示中文
    [转载] 在Linux中,开机自动运行普通用户的脚本程序
    elasticsearch中的filter与aggs
    GET和POST的区别
    Java NIO读书笔记2
    Java NIO读书笔记
    java之并发
    java中参数传递
    java中final关键字
    Java类的初始化过程及清理
  • 原文地址:https://www.cnblogs.com/purinliang/p/14044973.html
Copyright © 2020-2023  润新知