线段树--区间修改set,区间更新add

来源:互联网 发布:印刷报价软件好用吗 编辑:程序博客网 时间:2024/05/16 21:15


#include <iostream>

#include <cstdio>

#include <cstring>

using namespacestd;


const int maxn =1e6 +5;

const int INF =1 <<30;


int ql,qr,op;

int x1,x2,v;

int _sum,_min,_max;

struct tree{

    struct node{

        int minv,maxv,sumv;

        int add,set;

    }seg[maxn <<2];

    void pushup(int l,int r,int rt)

    {

        int lc = rt <<1,rc = lc |1;

        seg[rt].minv =min(seg[lc].minv,seg[rc].minv);

        seg[rt].maxv =max(seg[lc].maxv,seg[rc].maxv);

        seg[rt].sumv =seg[lc].sumv +seg[rc].sumv;

    }

    void pushdown(int l,int r,int rt)

    {

        int lc = rt <<1,rc = lc |1;

        int mid = (l + r) >>1;

        if(seg[rt].set){//v > 0

            int x =seg[rt].set;

            seg[lc].set =seg[rc].set = x;

            seg[lc].maxv =seg[rc].maxv = x;

            seg[lc].minv =seg[rc].minv = x;

            seg[lc].sumv = (mid - l +1) * x;seg[rc].sumv = (r - mid) * x;

            seg[rt].set =seg[lc].add =seg[rc].add =0;//set时,add就失效,变成0

        }

        if(seg[rt].add){

            int x =seg[rt].add;

            seg[lc].add += x;seg[rc].add += x;

            seg[lc].maxv += x;seg[rc].maxv += x;

            seg[lc].minv += x;seg[rc].minv += x;

            seg[lc].sumv += (mid - l +1) * x;seg[rc].sumv += (r - mid) * x;

            seg[rt].add =0;

        }

    }

    void update(int l,int r,int rt)

    {

        if(ql <= l && r <=qr){

            if(op ==1){

                seg[rt].add +=v;

                seg[rt].minv +=v;

                seg[rt].maxv +=v;

                seg[rt].sumv += (r - l +1) *v;

            }

            else{

                seg[rt].set =seg[rt].minv =seg[rt].maxv =v;

                seg[rt].sumv = (r - l +1) *v;

                seg[rt].add =0;

            }

            return;

        }

        pushdown(l, r, rt);

        int mid = (l + r) >>1;

        if(ql <= mid)update(l, mid, rt <<1);

        if(mid <qr)update(mid +1, r, rt <<1 |1);

        pushup(l, r, rt);

    }

    void query(int l,int r,int rt)

    {

        if(ql <= l && r <=qr){

            _sum +=seg[rt].sumv;

            _min =min(_min,seg[rt].minv);

            _max =max(_max,seg[rt].maxv);

            return;

        }

        pushdown(l, r, rt);

        int mid = (l + r) >>1;

        if(ql <= mid)query(l, mid, rt <<1);

        if(mid <qr)query(mid +1, r, rt <<1 |1);

    }

}trees[22];



int main()

{

    int r,c,m;

    while (scanf("%d%d%d",&r,&c,&m) !=EOF) {


        memset(trees,0,sizeof(trees));

        for (int i =0; i < m; i ++) {

            scanf("%d%d%d%d%d",&op,&x1,&ql,&x2,&qr);

            if(op <3){

                scanf("%d",&v);

                for (int j =x1; j <=x2; j ++) {

                    trees[j].update(1, c,1);

                }

            }

            else{

                _sum =0,_max = -INF,_min =INF;

                for (int j =x1; j <=x2; j ++) {

                    trees[j].query(1, c,1);

                }

                printf("%d %d %d\n",_sum,_min,_max);

            }

        }

    }

    return0;

}



原创粉丝点击