1. 程式人生 > >UVA11992 Fast Matrix Operations

UVA11992 Fast Matrix Operations

傳送門

發現最多隻有20行,所以開20個線段樹處理即可。當然存在更優的做法,就是一行接著一行,變成一個線段樹,節省空間。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1000006
#define lson (rt<<1)
#define rson (rt<<1|1)
#define mid ((l+r)>>1)
#define sizel (((l+r)>>1)-l+1)
#define sizer (r-((l+r)>>1))
#define INF 2147483647

struct Node {
    int seg,minn,maxx;
};

Node cmp(Node a,Node b) {
    return (Node){a.seg+b.seg,std::min(a.minn,b.minn),std::max(a.maxx,b.maxx)};
}

struct Segment_tree {
    
    int seg[MAXN<<2],minn[MAXN<<2],maxx[MAXN<<2];
    int sum[MAXN<<2],tag[MAXN<<2];
    
    void pushup(int rt) {
        seg[rt] = seg[lson] + seg[rson];
        minn[rt] = std::min(minn[lson],minn[rson]);
        maxx[rt] = std::max(maxx[lson],maxx[rson]);
    }

    void pushdown(int rt,int l,int r) {
        if(tag[rt]) {
            seg[lson] = tag[rt]*sizel; seg[rson] = tag[rt]*sizer;
            maxx[lson] = maxx[rson] = tag[rt];
            minn[lson] = minn[rson] = tag[rt];
            sum[lson] = sum[rson] = 0;
            tag[lson] = tag[rson] = tag[rt];
            tag[rt] = 0;
        }
            seg[lson] += sum[rt]*sizel; seg[rson] += sum[rt]*sizer;
            maxx[lson] += sum[rt]; maxx[rson] += sum[rt];
            minn[lson] += sum[rt]; minn[rson] += sum[rt];
            sum[lson] += sum[rt]; sum[rson] += sum[rt];
            sum[rt] = 0;
    }

    void sum_update(int C,int L,int R,int rt,int l,int r) {
        if(L<=l&&R>=r) {
            sum[rt] += C;
            seg[rt] += C*(r-l+1);
            maxx[rt] += C; minn[rt] += C;
            return;
        }
        if(L>r||R<l) return;
        pushdown(rt,l,r);
        if(L<=mid) sum_update(C,L,R,lson,l,mid);
        if(R>mid) sum_update(C,L,R,rson,mid+1,r);
        pushup(rt);
    }

    void tag_update(int C,int L,int R,int rt,int l,int r) {
        if(L<=l&&R>=r) {
            sum[rt] = 0;
            maxx[rt] = minn[rt] = tag[rt] = C;
            seg[rt] = C*(r-l+1);
            return;
        }
        if(L>r||R<l) return;
        pushdown(rt,l,r);
        if(L<=mid) tag_update(C,L,R,lson,l,mid);
        if(R>mid) tag_update(C,L,R,rson,mid+1,r);
        pushup(rt);
    }

    Node query(int L,int R,int rt,int l,int r) {
        if(L<=l&&R>=r) return (Node){seg[rt],minn[rt],maxx[rt]};
        if(L>r||R<l) return (Node){0,INF,0};
        pushdown(rt,l,r);
        Node ans = (Node){0,INF,0};
        if(L<=mid) ans = cmp(ans,query(L,R,lson,l,mid));
        if(R>mid) ans = cmp(ans,query(L,R,rson,mid+1,r));
        pushup(rt);
        return ans;
    }

}G[25];

int N,M,R;

int main() {

    int opt,x,y,u,v,K;
    scanf("%d%d%d",&N,&M,&R);
    for(int i=1;i<=R;++i) {
        scanf("%d%d%d%d%d",&opt,&x,&y,&u,&v);
        if(opt==3) {
            Node temp = (Node){0,INF,0};
            for(int j=x;j<=u;++j) temp = cmp(temp,G[j].query(y,v,1,1,M));
            printf("%d %d %d\n",temp.seg,temp.minn,temp.maxx);
        }
        else {
            scanf("%d",&K);
            if(opt==1) {
                for(int j=x;j<=u;++j) G[j].sum_update(K,y,v,1,1,M);
            }
            else {
                for(int j=x;j<=u;++j) G[j].tag_update(K,y,v,1,1,M);
            }
        }
    }

    return 0;
}