input
r c m r<=20,1<=m<=20000
m行操作
1 x1 y1 x2 y2 v add v
2 x1 y1 x2 y2 v set v
3 x1 y1 x2 y2 查询该矩阵中的sum,max,min
output
对于每个3操作输出sum,max,min
做法:每行建一颗线段树
1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #include <iostream> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <ctime> 11 #include <cmath> 12 #define INF 0x7fffffff 13 #define MAX 1000000 14 15 using namespace std; 16 17 struct node 18 { 19 int v,addv,setv,sum,min,max; 20 }; 21 int r,c,m,x1,yy1,x2,yy2,v,op,suma,mina,maxa; 22 node a[21][MAX*3]; 23 void pushdown(int &l,int &r,int &k,int&i) 24 { 25 if(a[i][k].setv==0&&a[i][k].addv==0) return; 26 int m=l+((r-l)>>1),lc=k<<1,rc=k<<1|1,allv=a[i][k].setv+a[i][k].addv; 27 if(a[i][k].setv) //有set操作时优先将set操作pushdown 28 { 29 a[i][lc].addv=a[i][rc].addv=a[i][k].addv; 30 a[i][lc].v=a[i][rc].v=a[i][lc].setv=a[i][rc].setv=a[i][k].setv; 31 a[i][lc].min=a[i][rc].min=a[i][lc].max=a[i][rc].max=allv; 32 a[i][lc].sum=(m-l+1)*allv; 33 a[i][rc].sum=(r-m)*allv; 34 a[i][k].setv=a[i][k].addv=0; 35 } 36 else //无set操作时只是add操作也要pushdown 37 { 38 a[i][lc].addv+=a[i][k].addv; 39 a[i][rc].addv+=a[i][k].addv; 40 a[i][lc].min+=a[i][k].addv; 41 a[i][rc].min+=a[i][k].addv; 42 a[i][lc].max+=a[i][k].addv; 43 a[i][rc].max+=a[i][k].addv; 44 a[i][lc].sum+=(m-l+1)*a[i][k].addv; 45 a[i][rc].sum+=(r-m)*a[i][k].addv; 46 a[i][k].addv=0; 47 } 48 // printf("l:%d r:%d setv:%d add:%d ",l,r,a[i][k].setv,a[i][k].addv); 49 } 50 void reset(int &l,int &r,int &k,int&i) 51 { 52 int m=l+((r-l)>>1),lc=k<<1,rc=k<<1|1; 53 a[i][k].sum=a[i][lc].sum+a[i][rc].sum+(r-l+1)*a[i][k].addv; 54 a[i][k].min=min(a[i][lc].min,a[i][rc].min)+a[i][k].addv; 55 a[i][k].max=max(a[i][lc].max,a[i][rc].max)+a[i][k].addv; 56 } 57 void setupdate(int l,int r,int k,int &i) 58 { 59 int lc=k<<1,rc=k<<1|1; 60 if(yy1<=l&&yy2>=r) 61 { 62 a[i][k].min=a[i][k].max=a[i][k].setv=a[i][k].v=v; 63 a[i][k].addv=0; 64 a[i][k].sum=(r-l+1)*v; 65 //printf("l:%d r:%d setv:%d add:%d ",l,r,a[i][k].setv,a[i][k].addv); 66 return; 67 } 68 pushdown(l,r,k,i); 69 int m=l+((r-l)>>1); 70 if(yy1<=m) setupdate(l,m,lc,i); 71 if(yy2>m) setupdate(m+1,r,rc,i); 72 reset(l,r,k,i); 73 } 74 void addupdate(int l,int r,int k,int &i) 75 { 76 int lc=k<<1,rc=k<<1|1; 77 if(yy1<=l&&yy2>=r) 78 { 79 a[i][k].addv+=v; 80 a[i][k].sum+=(r-l+1)*v; 81 a[i][k].min+=v; 82 a[i][k].max+=v; 83 return; 84 } 85 pushdown(l,r,k,i); 86 int m=l+((r-l)>>1); 87 if(yy1<=m) addupdate(l,m,lc,i); 88 if(yy2>m) addupdate(m+1,r,rc,i); 89 reset(l,r,k,i); 90 } 91 void query(int l,int r,int k,int& i,int add) 92 { 93 if(a[i][k].setv) 94 { 95 int allv=add+a[i][k].v+a[i][k].addv; 96 suma+=allv*(min(r,yy2)-max(l,yy1)+1); 97 mina=min(mina,allv); 98 maxa=max(maxa,allv); 99 //printf("addv:%d all:%d %d %d ",a[i][k].addv,add,mina,maxa); 100 return; 101 } 102 if(yy1<=l&&yy2>=r) 103 { 104 suma+=a[i][k].sum+(r-l+1)*add; 105 mina=min(mina,a[i][k].min+add); 106 maxa=max(maxa,a[i][k].max+add); 107 return; 108 } 109 int m=l+((r-l)>>1); 110 if(yy1<=m) query(l,m,k<<1,i,add+a[i][k].addv); 111 if(yy2>m) query(m+1,r,k<<1|1,i,add+a[i][k].addv); 112 } 113 int main() 114 { 115 freopen("/home/user/桌面/in","r",stdin); 116 while(scanf("%d%d%d",&r,&c,&m)==3) 117 { 118 for(int i=1;i<=r;i++) memset(a[i],0,sizeof(a[0][0])*3*c); 119 //memset(a,0,sizeof(a)); 120 while(m--) 121 { 122 scanf("%d%d%d%d%d",&op,&x1,&yy1,&x2,&yy2); 123 if(op==2) 124 { 125 scanf("%d",&v); 126 for(int i=x1;i<=x2;i++) setupdate(1,c,1,i); 127 //for(int i=1;i<3*c;i++) printf("%d:%d %d ",i,a[3][i].setv,a[3][i].addv); 128 //puts("set"); 129 } 130 else if(op==1) 131 { 132 scanf("%d",&v); 133 for(int i=x1;i<=x2;i++) addupdate(1,c,1,i); 134 //for(int i=1;i<3*c;i++) printf("%d:%d %d ",i,a[3][i].setv,a[3][i].addv); 135 //puts("add"); 136 } 137 else 138 { 139 suma=0; 140 mina=INF; 141 maxa=-INF-1; 142 //printf("row:%d-%d col:%d-%d ",x1,x2,yy1,yy2); 143 //for(int i=1;i<=r;i++) printf("rowsum:%d ",a[i][1].sum); 144 for(int i=x1;i<=x2;i++) query(1,c,1,i,0); 145 printf("%d %d %d ",suma,mina,maxa); 146 } 147 } 148 } 149 //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC); 150 return 0; 151 }