码迷,mamicode.com
首页 > 其他好文 > 详细

线段树模板整理

时间:2017-03-28 17:18:33      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:pre   mil   int   span   logs   max   oid   main   class   

一、点修改:

二、区间修改:

(1)区间中每点值直接修改为v。

sum = 0;
ma = 0;
mi = INT_INF;
query(x, y, 1, 1, N);

代码如下:

int sumv[MAXN << 2], maxv[MAXN << 2], minv[MAXN << 2], setv[MAXN << 2];
int sum, ma, mi;
void maintain(int id, int L, int R){
    int lc = id << 1, rc = id << 1 | 1;
    if(R > L){
        sumv[id] = sumv[lc] + sumv[rc];
        maxv[id] = max(maxv[lc], maxv[rc]);
        minv[id] = min(minv[lc], minv[rc]);
    }
    if(setv[id] >= 0){
        minv[id] = maxv[id] = setv[id];
        sumv[id] = setv[id] * (R - L + 1);
    }
}
void pushdown(int id){
    int lc = id << 1, rc = id << 1 | 1;
    if(setv[id] >= 0){
        setv[lc] = setv[rc] = setv[id];
        setv[id] = -1;
    }
}
void update(int l, int r, int id, int L, int R, int v){//l,r要询问的区间
    int lc = id << 1, rc = id << 1 | 1;
    if(l <= L && r >= R){
        setv[id] = v;
    }
    else{
        pushdown(id);
        int Mid = L + (R - L) / 2;
        if(l <= Mid) update(l, r, lc, L, Mid, v);
        else maintain(lc, L, Mid);
        if(r > Mid) update(l, r, rc, Mid + 1, R, v);
        else maintain(rc, Mid + 1, R);
    }
    maintain(id, L, R);
}
void query(int l, int r, int id, int L, int R){//l,r要询问的区间
    if(setv[id] >= 0){
        sum += setv[id] * (min(R, r) - max(L, l) + 1);
        ma = max(ma, setv[id]);
        mi = min(mi, setv[id]);
    }
    else if(l <= L && r >= R){
        sum += sumv[id];
        ma = max(ma, maxv[id]);
        mi = min(mi, minv[id]);
    }
    else{
        int Mid = L + (R - L) / 2;
        if(l <= Mid) query(l, r, id << 1, L, Mid);
        if(r > Mid) query(l, r, id << 1 | 1, Mid + 1, R);
    }
}

 

线段树模板整理

标签:pre   mil   int   span   logs   max   oid   main   class   

原文地址:http://www.cnblogs.com/tyty-Somnuspoppy/p/6633417.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!