码风良好70pts, 区间最值线段树求大佬调一下
查看原帖
码风良好70pts, 区间最值线段树求大佬调一下
784813
SakurajiamaMai楼主2024/7/1 10:45

70分, 不知道是哪里错了, 调了一天还没出来,求大佬调一下! 悬关

#include <bits/stdc++.h>
#define ls u << 1
#define rs u << 1 | 1
#define LL long long
#define inf 1000000000
using namespace std;
const int N = 5e5 + 10, mod = 1e9 + 7;
int a[N];
struct node{
    int l, r, tag1[2], tag2[2], num[2], vis[2], add;
    LL sum;
}tr[N << 2];

void make(int u, int x){
    tr[u].sum = tr[u].sum + 1LL * (tr[u].r - tr[u].l + 1) * x;
    tr[u].tag1[0] += x, tr[u].tag1[1] += x;
    tr[u].tag2[0] += x, tr[u].tag2[1] += x;
    tr[u].add += x;
}

void make1(int u, int x){
    if(x >= tr[u].tag1[0]) return;
    tr[u].sum = tr[u].sum - 1LL * tr[u].num[0] * (tr[u].tag1[0] - x);
    if(tr[u].tag2[0] == tr[u].tag1[0]) tr[u].tag2[0] = x;
    tr[u].tag1[0] = tr[u].vis[0] = x;
}
void make2(int u, int x){
    if(x <= tr[u].tag2[0]) return;
    tr[u].sum = tr[u].sum + 1LL * tr[u].num[1] * (x - tr[u].tag2[0]);
    if(tr[u].tag1[0] == tr[u].tag2[0]) tr[u].tag1[0] = x;
    tr[u].tag2[0] = tr[u].vis[1] = x;   
}
/*
    上次修改到 : 要加一个标记数组看看是否需要修改值
*/
void pushup(int u){
    tr[u].sum = tr[ls].sum + tr[rs].sum;
    tr[u].tag1[0] = max(tr[ls].tag1[0], tr[rs].tag1[0]); 
    if(tr[ls].tag1[0] == tr[rs].tag1[0]){
        tr[u].tag1[1] = max(tr[ls].tag1[1], tr[rs].tag1[1]);
        tr[u].num[0] = tr[ls].num[0] + tr[rs].num[0];
    } 
    else{
        tr[u].tag1[1] = min(tr[ls].tag1[0], tr[rs].tag1[0]);
        tr[u].tag1[1] = max({tr[u].tag1[1], tr[ls].tag1[1], tr[rs].tag1[1]}); 
        tr[u].num[0] = tr[ls].tag1[0] > tr[rs].tag1[0] ? tr[ls].num[0] : tr[rs].num[0];
    }
    tr[u].tag2[0] = min(tr[ls].tag2[0], tr[rs].tag2[0]); 
    if(tr[ls].tag2[0] == tr[rs].tag2[0]){
        tr[u].tag2[1] = min(tr[ls].tag2[1], tr[rs].tag2[1]);
        tr[u].num[1] = tr[ls].num[1] + tr[rs].num[1];
    } 
    else{
        tr[u].tag2[1] = max(tr[ls].tag2[0], tr[rs].tag2[0]);
        tr[u].tag2[1] = min({tr[u].tag2[1], tr[ls].tag2[1], tr[rs].tag2[1]}); 
        tr[u].num[1] = tr[ls].tag2[0] < tr[rs].tag2[0] ? tr[ls].num[1] : tr[rs].num[1];
    }
}

void pushdown(int u){
    if(tr[u].add != 0){
        make(ls, tr[u].add), make(rs, tr[u].add);
        tr[u].add = 0;
    }
    make1(ls, tr[u].tag1[0]), make1(rs, tr[u].tag1[0]);
    make2(ls, tr[u].tag2[0]), make2(rs, tr[u].tag2[0]);
}

void build(int u, int l, int r){
    if(l == r){
        tr[u] = {l, r, {a[l], -inf}, {a[l], inf}, {1, 1}, {-inf, inf}, 0, 1LL * a[l]};
        return;
    }
    tr[u] = {l, r, {-inf, -inf}, {inf, inf}, {0, 0}, {-inf, inf}, 0, 1LL * 0};
    int mid = l + r >> 1;
    build(ls, l, mid), build(rs, mid+1 ,r);
    pushup(u);
}

void modifyadd(int u, int l, int r, int x){
    if(tr[u].l >= l && tr[u].r <= r){
        make(u, x);
        return;
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    if(l <= mid) modifyadd(ls, l, r, x);
    if(r > mid) modifyadd(rs, l, r, x);
    pushup(u);
}

void modifymin(int u, int l, int r, int x){
    if(tr[u].tag1[0] <= x) return;
    if(tr[u].l >= l && tr[u].r <= r && x > tr[u].tag1[1]){
        make1(u, x);
        return;
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    if(l <= mid) modifymin(ls, l, r, x);
    if(r > mid) modifymin(rs, l, r, x);
    pushup(u);
}

void modifymax(int u, int l, int r, int x){
    if(tr[u].tag2[0] >= x) return;
    if(tr[u].l >= l && tr[u].r <= r && x < tr[u].tag2[1]){
        make2(u, x);
        return;
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    if(l <= mid) modifymax(ls, l, r, x);
    if(r > mid) modifymax(rs, l, r, x);
    pushup(u);
}

LL querysum(int u, int l, int r){
    if(tr[u].l >= l && tr[u].r <= r){
        return tr[u].sum;
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    LL res = 0;
    if(l <= mid) res += querysum(ls, l, r);
    if(r > mid) res += querysum(rs, l, r);
    return res;
}

int querymax(int u, int l, int r){
    if(tr[u].l >= l && tr[u].r <= r){
        return tr[u].tag1[0];
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1, res = -inf;
    if(l <= mid) res = max(res, querymax(ls, l, r));
    if(r > mid) res = max(res, querymax(rs, l, r));
    return res;
}

int querymin(int u, int l, int r){
    if(tr[u].l >= l && tr[u].r <= r){
        return tr[u].tag2[0];
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1, res = inf;
    if(l <= mid) res = min(res, querymin(ls, l, r));
    if(r > mid) res = min(res, querymin(rs, l, r));
    return res;
}

void debug(int i){
    cout << "----now----" << endl;
    cout << tr[i].l << " " << tr[i].r << endl;
    cout << tr[i].tag1[0] << " " << tr[i].tag1[1] << endl;
    cout << tr[i].tag2[0] << " " << tr[i].tag2[1] << endl;
    cout << tr[i].sum << endl;
    cout << "----end----" << endl;
}

signed main()
{
    // std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n; cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i];
    build(1, 1, n);
    int m; cin >> m;
    while(m--){
        int op, l, r; cin >> op >> l >> r;
        if(op == 1){
            int x; cin >> x;
            modifyadd(1, l, r, x);
        }
        else if(op == 2){
            int x; cin >> x;
            modifymax(1, l, r, x);
        }
        else if(op == 3){
            int x; cin >> x;
            modifymin(1, l, r, x);
        }
        else if(op == 4) printf("%lld\n", querysum(1, l, r));
        else if(op == 5) printf("%d\n", querymax(1, l, r));
        else if(op == 6) printf("%d\n", querymin(1, l, r));
    }
    return 0;
}

2024/7/1 10:45
加载中...