zoukankan      html  css  js  c++  java
  • 黑暗爆炸

    传送门

    1. 给一个区间[L,R] 加上一个数x
    2. 把一个区间[L,R] 里小于x 的数变成x
    3. 把一个区间[L,R] 里大于x 的数变成x
    4. 求区间[L,R] 的和
    5. 求区间[L,R] 的最大值
    6. 求区间[L,R] 的最小值

    由吉老师线段树基础进阶。增加了区间加操作
    但对于同时进行23操作的话,也多了一个特判,就是最大值修改时要判断最小值和次小值,也得进行修改
    其次,对于区间加操作,就是多加了一个lazy标记,用与区间加的向下传递操作,而且lazy的优先级是大于其他两个修改操作的

    其他方法就和之前的一样,维护一个最大值,次大值,最大值个数,最小值,次小值,最小值个数,每次修改都进行3种情况的分类讨论即可

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N = 5e5, INF = 1 << 30;
    int a[N];
    struct Segment_Tree{
        struct Node{
            int l, r;
            int mx, mxse, mxcnt; // 维护最大值
            int mi, mise, micnt; // 维护最小值
            ll sum, lazy; // 区间和
            #define l(p) tree[p].l
            #define r(p) tree[p].r
            #define mx(p) tree[p].mx
            #define mi(p) tree[p].mi
            #define mxse(p) tree[p].mxse
            #define mise(p) tree[p].mise
            #define mxcnt(p) tree[p].mxcnt
            #define micnt(p) tree[p].micnt
            #define sum(p) tree[p].sum
            #define lazy(p) tree[p].lazy
            #define lson (p << 1)
            #define rson (p << 1 | 1)
        } tree[N << 2];
        void pushup(int p) {
            sum(p) = sum(lson) + sum(rson);
            mx(p) = max(mx(lson), mx(rson));
            mi(p) = min(mi(lson), mi(rson));
            mxcnt(p) = micnt(p) = 0;
            if(mx(lson) == mx(rson)) {
                mxcnt(p) = mxcnt(lson) + mxcnt(rson);
                mxse(p) = max(mxse(lson), mxse(rson));
            }else {
                if(mx(lson) > mx(rson)) {
                    mxcnt(p) = mxcnt(lson);
                    mxse(p) = max(mxse(lson), mx(rson));
                }else {
                    mxcnt(p) = mxcnt(rson);
                    mxse(p) = max(mxse(rson), mx(lson));
                }
            }
            if(mi(lson) == mi(rson)) {
                micnt(p) = micnt(lson) + micnt(rson);
                mise(p) = min(mise(lson), mise(rson));
            }else {
                if(mi(lson) < mi(rson)) {
                    micnt(p) = micnt(lson);
                    mise(p) = min(mise(lson), mi(rson));
                }else {
                    micnt(p) = micnt(rson);
                    mise(p) = min(mise(rson), mi(lson));
                }
            }
        }
        void pushdown(int p) {
            if(lazy(p)) {
                mx(lson) += lazy(p); mx(rson) += lazy(p); mxse(lson) += lazy(p); mxse(rson) += lazy(p);
                mi(lson) += lazy(p); mi(rson) += lazy(p); mise(lson) += lazy(p); mise(rson) += lazy(p);
                lazy(lson) += lazy(p); lazy(rson) += lazy(p);
                sum(lson) += 1ll * (r(lson) - l(lson) + 1) * lazy(p);
                sum(rson) += 1ll * (r(rson) - l(rson) + 1) * lazy(p);
                lazy(p) = 0;
            }
            if(mx(lson) > mx(p)) {
                if(mi(lson) == mx(lson)) mi(lson) = mx(p);
                if(mise(lson) == mx(lson)) mise(lson) = mx(p);
                sum(lson) -= 1ll * (mx(lson) - mx(p)) * mxcnt(lson);
                mx(lson) = mx(p);
            }
            if(mx(rson) > mx(p)) {
                if(mi(rson) == mx(rson)) mi(rson) = mx(p);
                if(mise(rson) == mx(rson)) mise(rson) = mx(p);
                sum(rson) -= 1ll * (mx(rson) - mx(p)) * mxcnt(rson);
                mx(rson) = mx(p);
            }
            if(mi(lson) < mi(p)) {
                if(mx(lson) == mi(lson)) mx(lson) = mi(p);
                if(mxse(lson) == mi(lson)) mxse(lson) = mi(p);
                sum(lson) += 1ll * (mi(p) - mi(lson)) * micnt(lson);
                mi(lson) = mi(p);
            }
            if(mi(rson) < mi(p)) {
                if(mx(rson) == mi(rson)) mx(rson) = mi(p);
                if(mxse(rson) == mi(rson)) mxse(rson) = mi(p);
                sum(rson) += 1ll * (mi(p) - mi(rson)) * micnt(rson);
                mi(rson) = mi(p);
            }
        }
        void build(int p, int l, int r) {
            l(p) = l, r(p) = r; 
            lazy(p) = 0; mx(p) = mi(p) = sum(p) = 0;
            mxse(p) = -INF, mise(p) = INF;
            mxcnt(p) = micnt(p) = 0;
            if(l == r) {
                mx(p) = mi(p) = sum(p) = a[l];
                mxse(p) = -INF; mise(p) = INF;
                mxcnt(p) = micnt(p) = 1; lazy(p) = 0;
                return;
            }
            int mid = (l + r) >> 1;
            build(lson, l, mid); build(rson, mid + 1, r);
            pushup(p);
        }
        void Change_max(int p, int l, int r, ll x) { // [l, r] a[i] = max(x, a[i])
            if(mi(p) >= x) return;
            if(l <= l(p) && r(p) <= r && mise(p) > x) {
                if(mx(p) == mi(p)) mx(p) = x;
                if(mxse(p) == mi(p)) mxse(p) = x;
                sum(p) += 1ll * (x - mi(p)) * micnt(p); mi(p) = x;
                return;
            }
            pushdown(p);
            int mid = (l(p) + r(p)) >> 1;
            if(l <= mid) Change_max(lson, l, r, x);
            if(r > mid) Change_max(rson, l, r, x);
            pushup(p);
        }
        void Change_min(int p, int l, int r, ll x) { // [l,r] a[i] = min(x, a[i])
            if(mx(p) <= x) return;
            if(l <= l(p) && r(p) <= r && mxse(p) < x) {
                if(mi(p) == mx(p)) mi(p) = x;
                if(mise(p) == mx(p)) mise(p) = x;
                sum(p) -= 1ll * (mx(p) - x) * mxcnt(p); mx(p) = x;
                return;
            }
            pushdown(p);
            int mid = (l(p) + r(p)) >> 1;
            if(l <= mid) Change_min(lson, l, r, x);
            if(r > mid) Change_min(rson, l, r, x);
            pushup(p);
        }
        void Change_add(int p, int l, int r, ll x) {
            if(l <= l(p) && r(p) <= r) {
                mx(p) += x; mi(p) += x;
                mise(p) += x; mxse(p) += x;
                sum(p) += 1ll * (r(p) - l(p) + 1) * x;
                lazy(p) += x;
                return;
            }
            pushdown(p);
            int mid = (l(p) + r(p)) >> 1;
            if(l <= mid) Change_add(lson, l, r, x);
            if(r > mid) Change_add(rson, l, r, x);
            pushup(p);
        }
        int Query_min(int p, int l, int r) {
            if(l <= l(p) && r(p) <= r) return mi(p);
            pushdown(p);
            int mid = (l(p) + r(p)) >> 1;
            int ans = INF;
            if(l <= mid) ans = min(ans, Query_min(lson, l, r));
            if(r > mid) ans = min(ans, Query_min(rson, l, r));
            return ans;
        }
        int Query_max(int p, int l, int r) {
            if(l <= l(p) && r(p) <= r) return mx(p);
            pushdown(p);
            int mid = (l(p) + r(p)) >> 1;
            int ans = -INF;
            if(l <= mid) ans = max(ans, Query_max(lson, l, r));
            if(r > mid) ans = max(ans, Query_max(rson, l, r));
            return ans;
        }
        ll Query_sum(int p, int l, int r) {
            if(l <= l(p) && r(p) <= r) return sum(p);
            pushdown(p);
            int mid = (l(p) + r(p)) >> 1;
            ll ans = 0;
            if(l <= mid) ans += Query_sum(lson, l, r);
            if(r > mid) ans += Query_sum(rson, l, r);
            return ans;
        }
    } seg;
    int main(){
        int n; scanf("%d", &n);
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        int m; scanf("%d", &m);
        seg.build(1, 1, n);
        for(int i = 1; i <= m; i++) {
            int op, l, r;
            scanf("%d%d%d", &op, &l, &r);
            if(op == 1) {
                int x; scanf("%d", &x); seg.Change_add(1, l, r, x);
            }
            if(op == 2) {
                int x; scanf("%d", &x); seg.Change_max(1, l, r, x);
            }
            if(op == 3) {
                int x; scanf("%d", &x); seg.Change_min(1, l, r, x);
            }
            if(op == 4) printf("%lld
    ", seg.Query_sum(1, l, r));
            if(op == 5) printf("%d
    ", seg.Query_max(1, l, r));
            if(op == 6) printf("%d
    ", seg.Query_min(1, l, r));
        }
        return 0;
    }
    
    I‘m Stein, welcome to my blog
  • 相关阅读:
    80211-pcap包类型有3种link type
    node搭建多人博客
    mac快捷键
    阿里云搭建svn
    linux 常用命令
    node 日志
    启动tomcat
    kill redis
    利用新浪接口获取客户端ip
    网站loading的几种实现方法
  • 原文地址:https://www.cnblogs.com/Emcikem/p/14657359.html
Copyright © 2011-2022 走看看