線段樹(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);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章