线段树(2)区间修改

线段树(2)区间修改

快速序列操作I,给出一个n个元素的数组A1,A2,…,An,你的任务是设计一个数据结构支持一下两种操作
set(L, R, v): 把AL,AL+1,…,Ar的值全部修改为v(v>=0)
Query(L, R):计算子序列AL,AL+1,…Ar的元素和、最小值和最大值。

#include <cstdio>
#include <algorithm>
using namespace std;
#define LL(x) x<<1
#define RR(x) x<<1|1
typedef long long INT;
const int maxn = 500;
INT setv[maxn<<2] = {-1}, minv[maxn<<2], maxv[maxn<<2], sumv[maxn<<2], a[maxn<<2];
INT _min, _max, _sum, v;
int y1, y2;
void BuildTree(int L, int R, int o) {
    if (L == R) {
        maxv[o] = minv[o] = sumv[o] = a[L];
    } else {
        int mid = (L+R)/2;
        int lc = LL(o);
        int rc = RR(o);
        BuildTree(L, mid, lc);
        BuildTree(mid+1, R, rc);
        maxv[o] = max(maxv[lc], maxv[rc]);
        minv[o] = min(minv[lc], minv[rc]);
        sumv[o] = sumv[lc] + sumv[rc];
    }
}
void maintain(int l, int r, int o) {
    if (setv[o] >= 0) {
        maxv[o] = setv[o];
        minv[o] = setv[o];
        sumv[o] = setv[o] * (r-l+1);
    } else if (l < r) {
        int lc = LL(o);
        int rc = RR(o);
        sumv[o] = sumv[lc] + sumv[rc];
        maxv[o] = max(maxv[lc], maxv[rc]);
        minv[o] = min(minv[lc], minv[rc]);
    }
}
void pushdown(int o) {
    int lc = LL(o);
    int rc = RR(o);
    if (setv[o] >= 0) {
        setv[lc] = setv[rc] = setv[o];
        setv[o] = -1;
    }
}
void update(int l, int r, int o) {
    if (y1 <= l && y2 >= r) {
        setv[o] = v;
    } else {
        pushdown(o);
        int m = (l+r)/2;
        if (y1 <= m) {
            update(l, m, o*2);
        } else {
            maintain(l, m, o*2);
        }
        if (y2 > m) {
            update(m+1, r, o*2+1);
        } else {
            maintain(m+1, r, o*2+1);
        }
    }
    maintain(l, r, o);
}
void Query(int L, int R, int o) {
    if (setv[o] >= 0) {
        _sum += setv[o]*(min(R,y2)-max(y1,L)+1);    //BUG
        _min = min(_min, setv[o]);
        _max = max(_max, setv[o]);
    } else if (y1 <= L && y2 >= R) {
        _sum += sumv[o];
        _min = min(_min, minv[o]);
        _max = max(_max, maxv[o]);
    } else {
        int m = (L+R)/2;
        if (y1 <= m) Query(L, m, o*2);
        if (y2 > m) Query(m+1, R, o*2+1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值