1 #include<cstdio>
  2 #define INF 0x7FFFFFFF
  3 #define MAXN 1000010
  4 struct node
  5 {
  6     int cnt,son[4],kind[4];
  7     int big,small,sum,add,cover;
  8 };
  9 node tree[MAXN<<2];
 10 int size,SUM,BIG,SMALL;
 11 inline int MAX(int x,int y)
 12 {
 13     return x>y?x:y;
 14 }
 15 inline int MIN(int x,int y)
 16 {
 17     return x>y?y:x;
 18 }
 19 void Build(int x1,int x2,int y1,int y2,int rt)
 20 {
 21     tree[rt].cnt=0;
 22     tree[rt].big=tree[rt].small=tree[rt].sum=tree[rt].add=tree[rt].cover=0;
 23     if(x1!=x2||y1!=y2)
 24     {
 25         int i,mid1=(x1+x2)>>1,mid2=(y1+y2)>>1;
 26         if(x1<=mid1)
 27         {
 28             if(y1<=mid2)
 29             {
 30                 tree[rt].kind[tree[rt].cnt]=1;
 31                 tree[rt].son[tree[rt].cnt++]=size++;
 32             }
 33             if(y2>mid2)
 34             {
 35                 tree[rt].kind[tree[rt].cnt]=2;
 36                 tree[rt].son[tree[rt].cnt++]=size++;
 37             }
 38         }
 39         if(x2>mid1)
 40         {
 41             if(y1<=mid2)
 42             {
 43                 tree[rt].kind[tree[rt].cnt]=3;
 44                 tree[rt].son[tree[rt].cnt++]=size++;
 45             }
 46             if(y2>mid2)
 47             {
 48                 tree[rt].kind[tree[rt].cnt]=4;
 49                 tree[rt].son[tree[rt].cnt++]=size++;
 50             }
 51         }
 52         for(i=0;i<tree[rt].cnt;i++)
 53         {
 54             if(tree[rt].kind[i]==1)
 55                 Build(x1,mid1,y1,mid2,tree[rt].son[i]);
 56             else if(tree[rt].kind[i]==2)
 57                 Build(x1,mid1,mid2+1,y2,tree[rt].son[i]);
 58             else if(tree[rt].kind[i]==3)
 59                 Build(mid1+1,x2,y1,mid2,tree[rt].son[i]);
 60             else
 61                 Build(mid1+1,x2,mid2+1,y2,tree[rt].son[i]);
 62         }
 63     }
 64 }
 65 void PushDown(int x1,int x2,int mid1,int y1,int y2,int mid2,int rt)
 66 {
 67     int i;
 68     if(tree[rt].cover)
 69     {
 70         for(i=0;i<tree[rt].cnt;i++)
 71         {
 72             if(tree[rt].kind[i]==1)
 73                 tree[tree[rt].son[i]].sum=(mid1-x1+1)*(mid2-y1+1)*tree[rt].cover;
 74             else if(tree[rt].kind[i]==2)
 75                 tree[tree[rt].son[i]].sum=(mid1-x1+1)*(y2-mid2)*tree[rt].cover;
 76             else if(tree[rt].kind[i]==3)
 77                 tree[tree[rt].son[i]].sum=(x2-mid1)*(mid2-y1+1)*tree[rt].cover;
 78             else
 79                 tree[tree[rt].son[i]].sum=(x2-mid1)*(y2-mid2)*tree[rt].cover;
 80             tree[tree[rt].son[i]].add=0;
 81             tree[tree[rt].son[i]].cover=tree[tree[rt].son[i]].big=tree[tree[rt].son[i]].small=tree[rt].cover;
 82         }
 83         tree[rt].cover=0;
 84     }
 85     if(tree[rt].add)
 86     {
 87         for(i=0;i<tree[rt].cnt;i++)
 88         {
 89             if(tree[rt].kind[i]==1)
 90                 tree[tree[rt].son[i]].sum+=(mid1-x1+1)*(mid2-y1+1)*tree[rt].add;
 91             else if(tree[rt].kind[i]==2)
 92                 tree[tree[rt].son[i]].sum+=(mid1-x1+1)*(y2-mid2)*tree[rt].add;
 93             else if(tree[rt].kind[i]==3)
 94                 tree[tree[rt].son[i]].sum+=(x2-mid1)*(mid2-y1+1)*tree[rt].add;
 95             else
 96                 tree[tree[rt].son[i]].sum+=(x2-mid1)*(y2-mid2)*tree[rt].add;
 97             tree[tree[rt].son[i]].add+=tree[rt].add;
 98             tree[tree[rt].son[i]].big+=tree[rt].add;
 99             tree[tree[rt].son[i]].small+=tree[rt].add;
100         }
101         tree[rt].add=0;
102     }
103 }
104 void PushUp(int rt)
105 {
106     int i;
107     tree[rt].big=tree[rt].sum=0;
108     tree[rt].small=INF;
109     for(i=0;i<tree[rt].cnt;i++)
110     {
111         tree[rt].sum+=tree[tree[rt].son[i]].sum;
112         tree[rt].big=MAX(tree[rt].big,tree[tree[rt].son[i]].big);
113         tree[rt].small=MIN(tree[rt].small,tree[tree[rt].son[i]].small);
114     }
115 }
116 void Add(int x1,int x2,int y1,int y2,int val,int a,int b,int c,int d,int rt)
117 {
118     if(x1<=a&&b<=x2&&y1<=c&&d<=y2)
119     {
120         tree[rt].add+=val;
121         tree[rt].big+=val;
122         tree[rt].small+=val;
123         tree[rt].sum+=val*(b-a+1)*(d-c+1);
124     }
125     else
126     {
127         int mid1=(a+b)>>1,mid2=(c+d)>>1,i=0;
128         PushDown(a,b,mid1,c,d,mid2,rt);
129         if(x1<=mid1)
130         {
131             if(y1<=mid2)
132             {
133                 for(;tree[rt].kind[i]!=1&&i<tree[rt].cnt;i++);
134                 if(tree[rt].kind[i]==1)
135                     Add(x1,x2,y1,y2,val,a,mid1,c,mid2,tree[rt].son[i]);
136             }
137             if(y2>mid2)
138             {
139                 for(;tree[rt].kind[i]!=2&&i<tree[rt].cnt;i++);
140                 if(tree[rt].kind[i]==2)
141                     Add(x1,x2,y1,y2,val,a,mid1,mid2+1,d,tree[rt].son[i]);
142             }
143         }
144         if(x2>mid1)
145         {
146             if(y1<=mid2)
147             {
148                 for(;tree[rt].kind[i]!=3&&i<tree[rt].cnt;i++);
149                 if(tree[rt].kind[i]==3)
150                     Add(x1,x2,y1,y2,val,mid1+1,b,c,mid2,tree[rt].son[i]);
151             }
152             if(y2>mid2)
153             {
154                 for(;tree[rt].kind[i]!=4&&i<tree[rt].cnt;i++);
155                 if(tree[rt].kind[i]==4)
156                     Add(x1,x2,y1,y2,val,mid1+1,b,mid2+1,d,tree[rt].son[i]);
157             }
158         }
159         PushUp(rt);
160     }
161 }
162 void Cover(int x1,int x2,int y1,int y2,int val,int a,int b,int c,int d,int rt)
163 {
164     if(x1<=a&&b<=x2&&y1<=c&&d<=y2)
165     {
166         tree[rt].add=0;
167         tree[rt].cover=tree[rt].big=tree[rt].small=val;
168         tree[rt].sum=val*(b-a+1)*(d-c+1);
169     }
170     else
171     {
172         int mid1=(a+b)>>1,mid2=(c+d)>>1,i=0;
173         PushDown(a,b,mid1,c,d,mid2,rt);
174         if(x1<=mid1)
175         {
176             if(y1<=mid2)
177             {
178                 for(;tree[rt].kind[i]!=1&&i<tree[rt].cnt;i++);
179                 if(tree[rt].kind[i]==1)
180                     Cover(x1,x2,y1,y2,val,a,mid1,c,mid2,tree[rt].son[i]);
181             }
182             if(y2>mid2)
183             {
184                 for(;tree[rt].kind[i]!=2&&i<tree[rt].cnt;i++);
185                 if(tree[rt].kind[i]==2)
186                     Cover(x1,x2,y1,y2,val,a,mid1,mid2+1,d,tree[rt].son[i]);
187             }
188         }
189         if(x2>mid1)
190         {
191             if(y1<=mid2)
192             {
193                 for(;tree[rt].kind[i]!=3&&i<tree[rt].cnt;i++);
194                 if(tree[rt].kind[i]==3)
195                     Cover(x1,x2,y1,y2,val,mid1+1,b,c,mid2,tree[rt].son[i]);
196             }
197             if(y2>mid2)
198             {
199                 for(;tree[rt].kind[i]!=4&&i<tree[rt].cnt;i++);
200                 if(tree[rt].kind[i]==4)
201                     Cover(x1,x2,y1,y2,val,mid1+1,b,mid2+1,d,tree[rt].son[i]);
202             }
203         }
204         PushUp(rt);
205     }
206 }
207 void Query(int x1,int x2,int y1,int y2,int a,int b,int c,int d,int rt)
208 {
209     if(x1<=a&&b<=x2&&y1<=c&&d<=y2)
210     {
211         SUM+=tree[rt].sum;
212         BIG=MAX(BIG,tree[rt].big);
213         SMALL=MIN(SMALL,tree[rt].small);
214     }
215     else
216     {
217         int mid1=(a+b)>>1,mid2=(c+d)>>1,i=0;
218         PushDown(a,b,mid1,c,d,mid2,rt);
219         if(x1<=mid1)
220         {
221             if(y1<=mid2)
222             {
223                 for(;tree[rt].kind[i]!=1&&i<tree[rt].cnt;i++);
224                 if(tree[rt].kind[i]==1)
225                     Query(x1,x2,y1,y2,a,mid1,c,mid2,tree[rt].son[i]);
226             }
227             if(y2>mid2)
228             {
229                 for(;tree[rt].kind[i]!=2&&i<tree[rt].cnt;i++);
230                 if(tree[rt].kind[i]==2)
231                     Query(x1,x2,y1,y2,a,mid1,mid2+1,d,tree[rt].son[i]);
232             }
233         }
234         if(x2>mid1)
235         {
236             if(y1<=mid2)
237             {
238                 for(;tree[rt].kind[i]!=3&&i<tree[rt].cnt;i++);
239                 if(tree[rt].kind[i]==3)
240                     Query(x1,x2,y1,y2,mid1+1,b,c,mid2,tree[rt].son[i]);
241             }
242             if(y2>mid2)
243             {
244                 for(;tree[rt].kind[i]!=4&&i<tree[rt].cnt;i++);
245                 if(tree[rt].kind[i]==4)
246                     Query(x1,x2,y1,y2,mid1+1,b,mid2+1,d,tree[rt].son[i]);
247             }
248         }
249     }
250 }
251 int main()
252 {
253     int n,m,q;
254     int x1,y1,x2,y2,val,flag;
255     while(~scanf("%d%d%d",&n,&m,&q))
256     {
257         size=2;
258         Build(1,n,1,m,1);
259         while(q--)
260         {
261             scanf("%d%d%d%d%d",&flag,&x1,&y1,&x2,&y2);
262             if(flag==1)
263             {
264                 scanf("%d",&val);
265                 Add(x1,x2,y1,y2,val,1,n,1,m,1);
266             }
267             else if(flag==2)
268             {
269                 scanf("%d",&val);
270                 Cover(x1,x2,y1,y2,val,1,n,1,m,1);
271             }
272             else
273             {
274                 SUM=BIG=0;
275                 SMALL=INF;
276                 Query(x1,x2,y1,y2,1,n,1,m,1);
277                 printf("%d %d %d\n",SUM,SMALL,BIG);
278             }
279         }
280     }
281     return 0;
282 }
posted on 2012-06-30 09:59  DrunBee  阅读(854)  评论(0编辑  收藏  举报