线段树 24 分求调
查看原帖
线段树 24 分求调
549357
幸存者楼主2022/7/2 22:01
#include <bits/stdc++.h>
using namespace std;
int a[500010], w1[2000010], w2[2000010], lzy1[2000010], lzy2[2000010];
void maketag1(int u, int x)
{
    lzy1[u] += x, w1[u] += x, w2[u] += x;
}
void maketag2(int u, int x)
{
    lzy2[u] = w1[u] = w2[u] = x;
    lzy1[u] = 0;
}
void pushup(int u)
{
    w1[u] = min(w1[u << 1], w1[u << 1 | 1]);
    w2[u] = max(w2[u << 1], w2[u << 1 | 1]);
}
void pushdown(int u, int L, int R)
{
    int M = L + R >> 1;
    if (lzy2[u] > 0)
    {
        maketag2(u << 1, lzy2[u]);
        maketag2(u << 1 | 1, lzy2[u]);
        lzy2[u] = 0;
    }
    if (lzy1[u] > 0)
    {
        maketag1(u << 1, lzy1[u]);
        maketag1(u << 1 | 1, lzy1[u]);
        lzy1[u] = 0;
    }
}
void build(int u, int L, int R)
{
    if (L == R)
    {
        w1[u] = w2[u] = a[L];
        return;
    }
    int M = L + R >> 1;
    build(u << 1, L, M);
    build(u << 1 | 1, M + 1, R);
    pushup(u);
}
void update1(int u, int L, int R, int l, int r, int x)
{
    if (l <= L && R <= r) maketag1(u, x);
    else if (L <= r && R >= l)
    {
        int M = L + R >> 1;
        pushdown(u, L, R);
        update1(u << 1, L, M, l, r, x);
        update1(u << 1 | 1, M + 1, R, l, r, x);
        pushup(u);
    }
}
void update2(int u, int L, int R, int l, int r, int x)
{
    if (l <= L && R <= r)
    {
        if (w1[u] >= x)
        {
            lzy2[u] = w1[u] = w2[u] = x;
            lzy1[u] = 0;
            return;
        }
        if (w2[u] <= x) return;
        int M = L + R >> 1;
        pushdown(u, L, R);
        update2(u << 1, L, M, l, r, x);
        update2(u << 1 | 1, M + 1, R, l, r, x);
        pushup(u);
    }
    else if (L <= r && R >= l)
    {
        int M = L + R >> 1;
        pushdown(u, L, R);
        update2(u << 1, L, M, l, r, x);
        update2(u << 1 | 1, M + 1, R, l, r, x);
        pushup(u);
    }
}
void update3(int u, int L, int R, int l, int r, int x)
{
    if (l <= L && R <= r)
    {
        if (w2[u] <= x)
        {
            lzy2[u] = w1[u] = w2[u] = x;
            lzy1[u] = 0;
            return;
        }
        if (w1[u] >= x) return;
        int M = L + R >> 1;
        pushdown(u, L, R);
        update3(u << 1, L, M, l, r, x);
        update3(u << 1 | 1, M + 1, R, l, r, x);
        pushup(u);
    }
    else if (L <= r && R >= l)
    {
        int M = L + R >> 1;
        pushdown(u, L, R);
        update3(u << 1, L, M, l, r, x);
        update3(u << 1 | 1, M + 1, R, l, r, x);
        pushup(u);
    }
}
int query(int u, int L, int R, int l, int r)
{
    if (l <= L && R <= r) return w2[u];
    if (L <= r && R >= l)
    {
        int M = L + R >> 1;
        pushdown(u, L, R);
        return max(query(u << 1, L, M, l, r), query(u << 1 | 1, M + 1, R, l, r));
    }
    else return -1e9;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int n, q;
    cin >> n >> q;
    for (register int i = 1; i <= n; i++) cin >> a[i];
    build(1, 1, n);
    for (register int i = 1; i <= q; i++)
    {
        int op;
        cin >> op;
        if (op == 1)
        {
            int l, r, x;
            cin >> l >> r >> x;
            update1(1, 1, n, l, r, x);
        }
        else if (op == 2)
        {
            int l, r, x;
            cin >> l >> r >> x;
            update2(1, 1, n, l, r, x);
        }
        else if (op == 3)
        {
            int l, r, x;
            cin >> l >> r >> x;
            update3(1, 1, n, l, r, x);
        }
        else
        {
            int l, r;
            cin >> l >> r;
            cout << query(1, 1, n, l, r) << endl;
        }
    }
    return 0;
}
2022/7/2 22:01
加载中...