ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

黑暗爆炸 - 4695 最假女选手 - 吉老师线段树

2021-04-14 13:33:26  阅读:299  来源: 互联网

标签:lazy 4695 最假 int rson mi lson 女选手 mx


传送门

  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\n", seg.Query_sum(1, l, r));
        if(op == 5) printf("%d\n", seg.Query_max(1, l, r));
        if(op == 6) printf("%d\n", seg.Query_min(1, l, r));
    }
    return 0;
}

标签:lazy,4695,最假,int,rson,mi,lson,女选手,mx
来源: https://www.cnblogs.com/Emcikem/p/14657359.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有