HDU 5306 Gorgeous Sequence

5306 ( Gorgeous Sequence )

思路:

吉司机线段树

维护最大值和次大值,大于最大值不改,在最大值和次大值之间的直接修改,小于次大值递归修改。

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
//#define mp make_pair
#define pb push_back
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdi pair<double, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "
";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//head

inline int read() {
    int a = 1, b = 0;
    char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-') a = -1;
        ch = getchar();
    }
    while('0' <= ch && ch <= '9') {
        b = b*10 + ch-'0';
        ch = getchar();
    }
    return a*b;
}

const int N = 1e6 + 5;
int a[N], mx[N<<2], cnt[N<<2], se[N<<2], lazy[N<<2], n, m, op, x, y, t, T;
LL sum[N<<2];
inline void push_up(int rt) {
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    mx[rt] = max(mx[rt<<1], mx[rt<<1|1]);
    if(mx[rt<<1] > mx[rt<<1|1]) se[rt] = max(se[rt<<1], mx[rt<<1|1]), cnt[rt] = cnt[rt<<1];
    else if(mx[rt<<1] < mx[rt<<1|1]) se[rt] = max(se[rt<<1|1], mx[rt<<1]), cnt[rt] = cnt[rt<<1|1];
    else se[rt] = max(se[rt<<1], se[rt<<1|1]), cnt[rt] = cnt[rt<<1] + cnt[rt<<1|1];
}
inline void push_down(int rt) {
    if(lazy[rt] < mx[rt<<1]) sum[rt<<1] -= (mx[rt<<1] - lazy[rt])*1LL*cnt[rt<<1], mx[rt<<1] = lazy[rt], lazy[rt<<1] = lazy[rt];
    if(lazy[rt] < mx[rt<<1|1]) sum[rt<<1|1] -= (mx[rt<<1|1] - lazy[rt])*1LL*cnt[rt<<1|1], mx[rt<<1|1] = lazy[rt], lazy[rt<<1|1] = lazy[rt];
    lazy[rt] = 0;
}
void build(int rt, int l, int r) {
    lazy[rt] = 0;
    if(l == r) {
        sum[rt] = mx[rt] = a[l];
        se[rt] = -1;
        cnt[rt] = 1;
        return ;
    }
    int m = l+r >> 1;
    build(ls);
    build(rs);
    push_up(rt);
}
void update(int L, int R, int x, int rt, int l, int r) {
    if(mx[rt] <= x) return ;
    if(L <= l && r <= R) {
        if(l == r) {
            sum[rt] = mx[rt] = x;
            se[rt] = -1;
            cnt[rt] = 1;
            return ;
        }
        if(se[rt] < x && x < mx[rt]) {
            sum[rt] -= (mx[rt] - x)*1LL*cnt[rt];
            mx[rt] = x;
            lazy[rt] = x;
        }
        else {
            int m = l+r >> 1;
            if(lazy[rt]) push_down(rt);
            update(L, R, x, ls);
            update(L, R, x, rs);
            push_up(rt);
        }
        return ;
    }
    int m = l+r >> 1;
    if(lazy[rt]) push_down(rt);
    if(L <= m) update(L, R, x, ls);
    if(R  > m) update(L, R, x, rs);
    push_up(rt);
}
LL querysum(int L, int R, int rt, int l, int r) {
    if(L <= l && r <= R) return sum[rt];
    int m = l+r >> 1;
    LL ans = 0;
    if(lazy[rt]) push_down(rt);
    if(L <= m) ans += querysum(L, R, ls);
    if(R  > m) ans += querysum(L, R, rs);
    push_up(rt);
    return ans;
}
int querymx(int L, int R, int rt, int l, int r) {
    if(L <= l && r <= R) return mx[rt];
    int m = l+r >> 1;
    int ans = 0;
    if(lazy[rt]) push_down(rt);
    if(L <= m) ans = max(ans, querymx(L, R, ls));
    if(R  > m) ans = max(ans, querymx(L, R, rs));
    push_up(rt);
    return ans;
}
int main() {
    T = read();
    while(T--) {
        n = read(); m = read();
        for (int i = 1; i <= n; ++i) a[i] = read();
        build(1, 1, n);
        for (int i = 1; i <= m; ++i) {
            op = read();
            if(op == 0) {
                x = read();
                y = read();
                t = read();
                update(x, y, t, 1, 1, n);
            }
            else if(op == 1) {
                x = read();
                y = read();
                printf("%d
", querymx(x, y, 1, 1, n));
            }
            else {
                x = read();
                y = read();
                printf("%lld
", querysum(x, y, 1, 1, n));
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/widsom/p/10770416.html