• UVA11992 Fast Matrix Operations


    思路

    注意到最多20行,拆成20颗线段树即可

    注意set标记清空左右儿子的add,不要清空自己的add,因为这个set操作之后可能还有add存在这个节点上

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define int long long
    using namespace std;
    struct Node{
        int minx,maxx,sum,add,set,lson,rson;
    }Seg[5000000];
    struct QNode{
        int minx,maxx,sum;
    };
    int Nodecnt,r,c,m,root[30];
    void pushup(int o){
        Seg[o].sum=Seg[Seg[o].lson].sum+Seg[Seg[o].rson].sum;
        Seg[o].maxx=max(Seg[Seg[o].lson].maxx,Seg[Seg[o].rson].maxx);
        Seg[o].minx=min(Seg[Seg[o].lson].minx,Seg[Seg[o].rson].minx);
    }
    int New_Node(void){
        int o=++Nodecnt;
        Seg[o].add=Seg[o].lson=Seg[o].rson=Seg[o].maxx=Seg[o].minx=Seg[o].sum=0;
        Seg[o].set=-1;
        return o;
    }
    void pushdown(int o,int l,int r){
        int mid=(l+r)>>1;
        if(!Seg[o].lson)
            Seg[o].lson=New_Node();
        if(!Seg[o].rson)
            Seg[o].rson=New_Node();
        if(Seg[o].set!=-1){
            Seg[Seg[o].lson].set=Seg[o].set;
            Seg[Seg[o].rson].set=Seg[o].set;
            Seg[Seg[o].lson].sum=Seg[o].set*(mid-l+1);
            Seg[Seg[o].rson].sum=Seg[o].set*(r-mid);
            Seg[Seg[o].lson].maxx=Seg[o].set;
            Seg[Seg[o].rson].maxx=Seg[o].set;
            Seg[Seg[o].lson].minx=Seg[o].set;
            Seg[Seg[o].rson].minx=Seg[o].set;
            Seg[Seg[o].lson].add=0;
            Seg[Seg[o].rson].add=0;
            Seg[o].set=-1;
        }
        if(Seg[o].add){
            Seg[Seg[o].lson].add+=Seg[o].add;
            Seg[Seg[o].rson].add+=Seg[o].add;
            Seg[Seg[o].lson].sum+=Seg[o].add*(mid-l+1);
            Seg[Seg[o].rson].sum+=Seg[o].add*(r-mid);
            Seg[Seg[o].lson].maxx+=Seg[o].add;
            Seg[Seg[o].rson].maxx+=Seg[o].add;
            Seg[Seg[o].lson].minx+=Seg[o].add;
            Seg[Seg[o].rson].minx+=Seg[o].add;
            Seg[o].add=0;
        }
    }   
    void add(int L,int R,int l,int r,int &o,int c){
        if(!o)
            o=New_Node();
        if(L<=l&&r<=R){
            Seg[o].add+=c;
            Seg[o].maxx+=c;
            Seg[o].minx+=c;
            Seg[o].sum+=c*(r-l+1);
            return;
        }
        pushdown(o,l,r);
        int mid=(l+r)>>1;
        if(L<=mid)
            add(L,R,l,mid,Seg[o].lson,c);
        if(R>mid)
            add(L,R,mid+1,r,Seg[o].rson,c);
        pushup(o);
    }
    void set(int L,int R,int l,int r,int &o,int c){
        if(!o)
            o=New_Node();
        if(L<=l&&r<=R){
            Seg[o].add=0;
            Seg[o].set=c;
            Seg[o].maxx=c;
            Seg[o].minx=c;
            Seg[o].sum=c*(r-l+1);
            return;
        }
        pushdown(o,l,r);
        int mid=(l+r)>>1;
        if(L<=mid)
            set(L,R,l,mid,Seg[o].lson,c);
        if(R>mid)
            set(L,R,mid+1,r,Seg[o].rson,c);
        pushup(o);
    }
    QNode query(int L,int R,int l,int r,int &o){
        if(!o)
            o=New_Node();
        QNode tmp;
        if(L<=l&&r<=R){
            tmp.maxx=Seg[o].maxx;
            tmp.minx=Seg[o].minx;
            tmp.sum=Seg[o].sum;
            return tmp;
        }
        pushdown(o,l,r);
        int mid=(l+r)>>1;
        if(R<=mid)
            return query(L,R,l,mid,Seg[o].lson);
        else if(L>mid)
            return query(L,R,mid+1,r,Seg[o].rson);
        else{
            QNode lx,rx;
            lx=query(L,R,l,mid,Seg[o].lson);
            rx=query(L,R,mid+1,r,Seg[o].rson);
            tmp.minx=min(lx.minx,rx.minx);
            tmp.maxx=max(lx.maxx,rx.maxx);
            tmp.sum=lx.sum+rx.sum;
            return tmp;
        }
    }
    void init(void){
        Nodecnt=0;
        memset(root,0,sizeof(root));
        Seg[0].maxx=-0x3f3f3f3f;
        Seg[0].minx=0x3f3f3f3f;
        Seg[0].sum=0;
    }
    signed main(){
        // freopen("test.in","r",stdin);
        // freopen("test.out","w",stdout);
        while(scanf("%lld %lld %lld",&r,&c,&m)==3){
            init();
            int x1,y1,x2,y2,v,opt;
            for(int i=1;i<=m;i++){
                scanf("%lld %lld %lld %lld %lld",&opt,&x1,&y1,&x2,&y2);
                if(opt==1){
                    scanf("%lld",&v);
                    for(int j=x1;j<=x2;j++)
                        add(y1,y2,1,c,root[j],v);
                }
                else if(opt==2){
                    scanf("%lld",&v);
                    for(int j=x1;j<=x2;j++)
                        set(y1,y2,1,c,root[j],v);
                }
                else{
                    QNode ans={0x3f3f3f3f,-0x3f3f3f3f,0},tmp;
                    for(int j=x1;j<=x2;j++){
                        tmp=query(y1,y2,1,c,root[j]);
                        ans.maxx=max(ans.maxx,tmp.maxx);
                        ans.minx=min(ans.minx,tmp.minx);
                        ans.sum=ans.sum+tmp.sum;
                    }
                    printf("%lld %lld %lld
    ",ans.sum,ans.minx,ans.maxx);
                }
            }
            // printf("0:%lld %lld %lld
    ",Seg[0].maxx,Seg[0].minx,Seg[0].sum);
        }
        return 0;
    }
    
  • 相关阅读:
    Java修饰符大汇总
    死锁
    线程的几种可用状态
    重载与覆盖(重写)
    Git
    JS跨域
    Spring中的Bean
    ZooKeeper
    Mysql(2)
    Maven
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10687571.html
Copyright © 2020-2023  润新知