UVA11992 Fast Matrix Operations
阿新 • • 發佈:2018-12-01
發現最多隻有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; }