uva 11992Fast Matrix Operations (線段樹區間各種操作,二維轉一維)
阿新 • • 發佈:2018-12-19
每行建立一顆線段樹,實現區間add,set查詢,注意set放在add前,每次set清空add
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 1000005 #define inf 0x3f3f3f3f #define lson 2*i,l,m #define rson 2*i+1,m+1,r int amax[25]; int amin[25]; int asum[25]; int setv[maxn*5]; int addv[maxn*5]; int sum[maxn*5]; int maxv[maxn*5]; int minv[maxn*5]; int r,c,m; using namespace std; void build(int k,int i,int l,int r) { int t=k*4*c; setv[t+i]=-1; addv[t+i]=0; sum[t+i]=0; minv[t+i]=0; maxv[t+i]=0; if(l==r) return ; int m=(l+r)/2; build(k,lson); build(k,rson); } void pushdown(int k,int i,int l,int r) { int t=k*4*c; int m=(l+r)/2; if(setv[t+i]!=-1) {if(l!=r) {addv[t+i*2]=addv[t+i*2+1]=0; setv[t+i*2]=setv[t+i*2+1]=setv[t+i]; sum[t+i*2]=setv[t+i]*(m-l+1); sum[t+i*2+1]=setv[t+i]*(r-m); maxv[t+i*2]=maxv[t+i*2+1]=minv[t+i*2]=minv[t+i*2+1]=setv[t+i]; } setv[t+i]=-1; } if(addv[t+i]>0) {if(l!=r) {addv[t+i*2]+=addv[t+i]; addv[t+i*2+1]+=addv[t+i]; sum[t+i*2]+=addv[t+i]*(m-l+1); sum[t+i*2+1]+=addv[t+i]*(r-m); maxv[t+i*2+1]+=addv[t+i]; maxv[t+i*2]+=addv[t+i]; minv[t+i*2]+=addv[t+i]; minv[t+i*2+1]+=addv[t+i]; } addv[t+i]=0; } } void pushup(int k,int i,int l,int r) { int t=k*4*c; sum[t+i]=sum[t+i*2]+sum[t+i*2+1]; maxv[t+i]=max(maxv[t+i*2],maxv[t+i*2+1]); minv[t+i]=min(minv[t+i*2],minv[t+i*2+1]); } void updateadd(int k,int ql,int qr,int v,int i,int l,int r) { int t=k*4*c; if(ql<=l&&r<=qr) { addv[t+i]+=v; sum[t+i]+=v*(r-l+1); maxv[t+i]+=v; minv[t+i]+=v; return ; } pushdown(k,i,l,r); int m=(l+r)>>1; if(ql<=m) updateadd(k,ql,qr,v,lson); if(m<qr) updateadd(k,ql,qr,v,rson); pushup(k,i,l,r); } void updateset(int k,int ql,int qr,int v,int i,int l,int r) { int t=k*4*c; if(ql<=l&&r<=qr) { setv[t+i]=v; addv[t+i]=0; sum[t+i]=v*(r-l+1); maxv[t+i]=v; minv[t+i]=v; return ; } pushdown(k,i,l,r); int m=(l+r)/2; if(ql<=m) updateset(k,ql,qr,v,lson); if(m<qr) updateset(k,ql,qr,v,rson); pushup(k,i,l,r); } void query(int k,int ql,int qr,int i,int l,int r) { int t=k*4*c; if(ql<=l&&r<=qr) { asum[k]+=sum[t+i]; amin[k]=min(amin[k],minv[t+i]); amax[k]=max(amax[k],maxv[t+i]); return ; } pushdown(k,i,l,r); int m=(l+r)/2; if(ql<=m) query(k,ql,qr,lson); if(m<qr) query(k,ql,qr,rson); } int main() { while(~scanf("%d%d%d",&r,&c,&m)) {for(int i=1;i<=r;i++) build(i,1,1,c); while(m--) { int op,x1,x2,y1,y2,v; scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2); if(op!=3) scanf("%d",&v); if(op==1) { for(int i=x1;i<=x2;i++) updateadd(i,y1,y2,v,1,1,c); } else if(op==2) { for(int i=x1;i<=x2;i++) updateset(i,y1,y2,v,1,1,c); } else if(op==3) { memset(asum,0,sizeof(asum)); for(int i=0;i<=r;i++) { amax[i]=-inf; amin[i]=inf; } int sumv=0,minv=inf,maxv=-inf; for(int i=x1;i<=x2;i++) {query(i,y1,y2,1,1,c); sumv+=asum[i]; maxv=max(maxv,amax[i]); minv=min(minv,amin[i]); } printf("%d %d %d\n",sumv,minv,maxv); } } } return 0; }