UVA 11992 - Fast Matrix Operations

给定一个r*c(r<=20,r*c<=1e6)的矩阵,其元素都是0,现在对其子矩阵进行操作。

1 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素add上val;

2 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素set为val;

3 x1 y1 x2 y2 val 表示输出(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素的sum,最大最小值max,min;

思路:线段树区间更新+lazy

每行维护一个线段树,然后,线段树维护四个值,max,min,sum,set,add。如果当前set,add都有值,那么先操作set再add,复杂度(n*log(n));

  1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<string.h>
5 #include<queue>
6 #include<stack>
7 #include<math.h>
8 using namespace std;
9 typedef long long LL;
10 typedef struct node
11 {
12 int addv;
13 int setv;
14 int maxx;
15 int minn;
16 int sum;
17 int l;
18 int r;
19 node()
20 {
21 addv = 0;
22 setv = 0;
23 maxx = 0;
24 sum = 0;
25 }
26 } tr;
27 tr tree[30][100005*8];
28 tr flag[100005*8];
29 void build(int l,int r,int k);
30 void update(int k,int id);
31 void add(int l,int r,int k,int nn,int mm,int id,int a);
32 void sett(int l,int r,int k,int nn,int mm,int id,int a);
33 int asksum(int l,int r,int k,int nn,int mm,int id);
34 int askminn(int l,int r,int k,int nn,int mm,int id);
35 int askmaxx(int l,int r,int k,int nn,int mm,int id);
36 int main(void)
37 {
38 int n,m,q;
39 while(scanf("%d %d %d",&n,&m,&q)!=EOF)
40 { memset(tree,0,sizeof(tree));
41 memset(flag,0,sizeof(flag));build(1,m,0);
42 while(q--)
43 {
44 int val ;
45 scanf("%d",&val);
46 if(val == 1)
47 {
48 int x1,y1,x2,y2,v;
49 scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&v);
50 int i,j;
51 for(i = x1;i <= x2;i++)
52 {
53 add(y1,y2,0,1,m,i,v);
54 }
55 }
56 else if(val == 2)
57 {
58 int x1,y1,x2,y2,v;int i,j;
59 scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&v);
60 for(i = x1;i <= x2;i++)
61 {
62 sett(y1,y2,0,1,m,i,v);
63 }
64 }
65 else
66 {
67 int x1,y1,x2,y2;int i,j;
68 scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
69 int su = 0;int ma = 0;int mi = 1e9;
70 for(i = x1;i <= x2;i++)
71 {
72 su += asksum(y1,y2,0,1,m,i);
73 ma = max(askmaxx(y1,y2,0,1,m,i),ma);
74 mi = min(mi,askminn(y1,y2,0,1,m,i));
75 }
76 printf("%d %d %d\n",su,mi,ma);
77 }
78 }
79 }
80 return 0;
81 }
82 void build(int l,int r,int k)
83 {
84 if(l == r)
85 {
86 flag[k].l = l;
87 flag[k].r = r;
88 return ;
89 }
90 else
91 {
92 flag[k].l = l;
93 flag[k].r = r;
94 build(l,(l+r)/2,2*k+1);
95 build((l+r)/2+1,r,2*k+2);
96 }
97 }
98 void update(int k,int id)
99 {
100 while(k>0)
101 {
102 k = (k-1)/2;
103 int x1 = 2*k+1;
104 int x2 = 2*k+2;
105 if(tree[id][x1].setv)
106 { //printf("1\n");
107 int xx1 = x1;
108 tree[id][2*xx1+1].setv = tree[id][x1].setv;
109 tree[id][2*xx1+2].setv = tree[id][x1].setv;
110 tree[id][2*xx1+1].addv = tree[id][x1].addv;
111 tree[id][2*xx1+2].addv = tree[id][x1].addv;
112 tree[id][x1].maxx = tree[id][x1].setv + tree[id][x1].addv;
113 tree[id][x1].minn = tree[id][x1].setv + tree[id][x1].addv;
114 tree[id][x1].sum = tree[id][x1].maxx*(flag[x1].r-flag[x1].l+1);
115 tree[id][x1].setv = 0;
116 tree[id][x1].addv = 0;
117 }
118 else if(tree[id][x1].addv)
119 {
120 int xx1 = x1;
121 tree[id][2*xx1+1].addv += tree[id][x1].addv;
122 tree[id][2*xx1+2].addv += tree[id][x1].addv;
123 tree[id][x1].maxx = tree[id][x1].maxx + tree[id][x1].addv;
124 tree[id][x1].minn = tree[id][x1].minn + tree[id][x1].addv;
125 tree[id][x1].sum += (flag[x1].r-flag[x1].l+1)*(tree[id][x1].addv);
126 tree[id][x1].setv = 0;
127 tree[id][x1].addv = 0;
128 }
129 if(tree[id][x2].setv)
130 {
131 int xx1 = x2;
132 tree[id][2*xx1+1].setv = tree[id][x2].setv;
133 tree[id][2*xx1+2].setv = tree[id][x2].setv;
134 tree[id][2*xx1+1].addv = tree[id][x2].addv;
135 tree[id][2*xx1+2].addv = tree[id][x2].addv;
136 tree[id][x2].maxx = tree[id][x2].setv + tree[id][x2].addv;
137 tree[id][x2].minn = tree[id][x2].setv + tree[id][x2].addv;
138 tree[id][x2].sum = tree[id][x2].maxx*(flag[x2].r-flag[x2].l+1);
139 tree[id][x2].setv = 0;
140 tree[id][x2].addv = 0;
141 }
142 else if(tree[id][x2].addv)
143 { //printf("%d\n",1);
144 int xx1 = x2;
145 tree[id][2*xx1+1].addv += tree[id][x2].addv;
146 tree[id][2*xx1+2].addv += tree[id][x2].addv;
147 tree[id][x2].maxx = tree[id][x2].maxx + tree[id][x2].addv;
148 tree[id][x2].minn = tree[id][x2].minn + tree[id][x2].addv;
149 tree[id][x2].sum += (flag[x2].r-flag[x2].l+1)*(tree[id][x2].addv);
150 tree[id][x2].setv = 0;
151 tree[id][x2].addv = 0;
152 }
153 tree[id][k].maxx = max(tree[id][x1].maxx,tree[id][x2].maxx);
154 tree[id][k].minn = min(tree[id][x1].minn,tree[id][x2].minn);
155 tree[id][k].sum = tree[id][x1].sum+tree[id][x2].sum;
156 }
157 }
158 void add(int l,int r,int k,int nn,int mm,int id,int a)
159 {
160 if(l > mm||r < nn)
161 return ;
162 else if(l <= nn&&r >= mm)
163 {
164 tree[id][k].addv += a;
165 if(tree[id][k].setv )
166 {
167 tree[id][2*k+1].setv = tree[id][k].setv;
168 tree[id][2*k+2].setv = tree[id][k].setv;
169 tree[id][2*k+1].addv = tree[id][k].addv;
170 tree[id][2*k+2].addv = tree[id][k].addv;
171 tree[id][k].sum = (tree[id][k].setv + tree[id][k].addv)*(mm-nn+1);
172 tree[id][k].maxx = tree[id][k].setv + tree[id][k].addv;
173 tree[id][k].minn = tree[id][k].setv + tree[id][k].addv;
174 tree[id][k].setv = 0;
175 tree[id][k].addv = 0;
176 // update(k,id);
177 }
178 else
179 {
180 tree[id][2*k+1].addv += tree[id][k].addv;
181 tree[id][2*k+2].addv += tree[id][k].addv;
182 //printf("%d\n",tree[id][2*k+1].addv);
183 tree[id][k].sum += (mm-nn+1)*tree[id][k].addv;
184 tree[id][k].maxx += tree[id][k].addv;
185 tree[id][k].minn += tree[id][k].addv;
186 tree[id][k].addv = 0;
187 //printf("%d\n",tree[id][k].sum);
188 }
189 update(k,id);
190 }
191 else
192 {
193 if(tree[id][k].setv)
194 {
195 tree[id][2*k+1].setv = tree[id][k].setv;
196 tree[id][2*k+2].setv = tree[id][k].setv;
197 tree[id][2*k+1].addv = tree[id][k].addv;
198 tree[id][2*k+2].addv = tree[id][k].addv;
199 tree[id][k].setv = 0;
200 tree[id][k].addv = 0;
201 }
202 else if(tree[id][k].addv)
203 {
204 tree[id][2*k+1].addv += tree[id][k].addv ;
205 tree[id][2*k+2].addv += tree[id][k].addv;
206 tree[id][k].addv = 0;
207 }
208 add(l,r,2*k+1,nn,(nn+mm)/2,id,a);
209 add(l,r,2*k+2,(nn+mm)/2+1,mm,id,a);
210 }
211 }
212 void sett(int l,int r,int k,int nn,int mm,int id,int a)
213 {
214 if(l > mm||r < nn)
215 return ;
216 else if(l <= nn&&r >= mm)
217 {
218 tree[id][k].setv = a;
219 if(tree[id][k].setv != 0)
220 {
221 tree[id][k].addv = 0;
222 tree[id][2*k+1].setv = tree[id][k].setv;
223 tree[id][2*k+2].setv = tree[id][k].setv;
224 tree[id][2*k+1].addv = tree[id][k].addv;
225 tree[id][2*k+2].addv = tree[id][k].addv;
226 tree[id][k].sum = (tree[id][k].setv + tree[id][k].addv)*(mm-nn+1);
227 tree[id][k].maxx = tree[id][k].setv + tree[id][k].addv;
228 tree[id][k].minn = tree[id][k].setv + tree[id][k].addv;
229 tree[id][k].setv = 0;
230 tree[id][k].addv = 0;
231 }
232 update(k,id);
233 }
234 else
235 {
236 if(tree[id][k].setv)
237 {
238 tree[id][2*k+1].setv = tree[id][k].setv;
239 tree[id][2*k+2].setv = tree[id][k].setv;
240 tree[id][2*k+1].addv = tree[id][k].addv;
241 tree[id][2*k+2].addv = tree[id][k].addv;
242 tree[id][k].setv = 0;
243 tree[id][k].addv = 0;
244 }
245 else if(tree[id][k].addv)
246 {
247 tree[id][2*k+1].addv += tree[id][k].addv ;
248 tree[id][2*k+2].addv += tree[id][k].addv;
249 tree[id][k].addv = 0;
250 }
251 sett(l,r,2*k+1,nn,(nn+mm)/2,id,a);
252 sett(l,r,2*k+2,(nn+mm)/2+1,mm,id,a);
253 }
254 }
255 int asksum(int l,int r,int k,int nn,int mm,int id)
256 {
257 if(l>mm||r<nn)
258 return 0;
259 else if(l <= nn&&r>=mm)
260 { //printf("%d %d\n",id,k);
261 if(tree[id][k].setv )
262 {
263 tree[id][2*k+1].setv = tree[id][k].setv;
264 tree[id][2*k+2].setv = tree[id][k].setv;
265 tree[id][2*k+1].addv = tree[id][k].addv;
266 tree[id][2*k+2].addv = tree[id][k].addv;
267 tree[id][k].sum = (tree[id][k].setv + tree[id][k].addv)*(mm-nn+1);
268 tree[id][k].maxx = tree[id][k].setv + tree[id][k].addv;
269 tree[id][k].minn = tree[id][k].setv + tree[id][k].addv;
270 tree[id][k].setv = 0;
271 tree[id][k].addv = 0; update(k,id);
272 }
273 else if(tree[id][k].addv)
274 {
275 tree[id][2*k+1].addv += tree[id][k].addv;
276 tree[id][2*k+2].addv += tree[id][k].addv;
277 tree[id][k].sum += (mm-nn+1)*tree[id][k].addv;
278 tree[id][k].maxx += tree[id][k].addv;
279 tree[id][k].minn += tree[id][k].addv;
280 tree[id][k].addv = 0; update(k,id);
281 }
282 return tree[id][k].sum;
283 }
284 else
285 {
286 if(tree[id][k].setv)
287 {
288 tree[id][2*k+1].setv = tree[id][k].setv;
289 tree[id][2*k+2].setv = tree[id][k].setv;
290 tree[id][2*k+1].addv = tree[id][k].addv;
291 tree[id][2*k+2].addv = tree[id][k].addv;
292 tree[id][k].setv = 0;
293 tree[id][k].addv = 0;
294 }
295 else if(tree[id][k].addv)
296 {
297 tree[id][2*k+1].addv += tree[id][k].addv ;
298 tree[id][2*k+2].addv += tree[id][k].addv;
299 tree[id][k].addv = 0;
300 }
301 int nx = asksum(l,r,2*k+1,nn,(nn+mm)/2,id);
302 int ny = asksum(l,r,2*k+2,(nn+mm)/2+1,mm,id);
303 return nx+ny;
304 }
305
306 }
307 int askminn(int l,int r,int k,int nn,int mm,int id)
308 {
309 if(l>mm||r<nn)
310 return 1e9;
311 else if(l <= nn&&r>=mm)
312 {
313 if(tree[id][k].setv != 0)
314 {
315 tree[id][2*k+1].setv = tree[id][k].setv;
316 tree[id][2*k+2].setv = tree[id][k].setv;
317 tree[id][2*k+1].addv = tree[id][k].addv;
318 tree[id][2*k+2].addv = tree[id][k].addv;
319 tree[id][k].sum = (tree[id][k].setv + tree[id][k].addv)*(mm-nn+1);
320 tree[id][k].maxx = tree[id][k].setv + tree[id][k].addv;
321 tree[id][k].minn = tree[id][k].setv + tree[id][k].addv;
322 tree[id][k].setv = 0;
323 tree[id][k].addv = 0; update(k,id);
324 }
325 else if(tree[id][k].addv)
326 {
327 tree[id][2*k+1].addv += tree[id][k].addv;
328 tree[id][2*k+2].addv += tree[id][k].addv;
329 tree[id][k].sum += (mm-nn+1)*tree[id][k].addv;
330 tree[id][k].maxx += tree[id][k].addv;
331 tree[id][k].minn += tree[id][k].addv;
332 tree[id][k].addv = 0; update(k,id);
333 }
334 // update(k,id);
335 return tree[id][k].minn;
336 }
337 else
338 {
339 if(tree[id][k].setv)
340 {
341 tree[id][2*k+1].setv = tree[id][k].setv;
342 tree[id][2*k+2].setv = tree[id][k].setv;
343 tree[id][2*k+1].addv = tree[id][k].addv;
344 tree[id][2*k+2].addv = tree[id][k].addv;
345 tree[id][k].setv = 0;
346 tree[id][k].addv = 0;
347 }
348 else if(tree[id][k].addv)
349 {
350 tree[id][2*k+1].addv += tree[id][k].addv ;
351 tree[id][2*k+2].addv += tree[id][k].addv;
352 tree[id][k].addv = 0;
353 }
354 int nx = askminn(l,r,2*k+1,nn,(nn+mm)/2,id);
355 int ny = askminn(l,r,2*k+2,(nn+mm)/2+1,mm,id);
356 return min(nx,ny);
357 }
358 }
359 int askmaxx(int l,int r,int k,int nn,int mm,int id)
360 {
361 if(l>mm||r<nn)
362 return 0;
363 else if(l <= nn&&r>=mm)
364 {
365 if(tree[id][k].setv != 0)
366 {
367 tree[id][2*k+1].setv = tree[id][k].setv;
368 tree[id][2*k+2].setv = tree[id][k].setv;
369 tree[id][2*k+1].addv = tree[id][k].addv;
370 tree[id][2*k+2].addv = tree[id][k].addv;
371 tree[id][k].sum = (tree[id][k].setv + tree[id][k].addv)*(mm-nn+1);
372 tree[id][k].maxx = tree[id][k].setv + tree[id][k].addv;
373 tree[id][k].minn = tree[id][k].setv + tree[id][k].addv;
374 tree[id][k].setv = 0;
375 tree[id][k].addv = 0; update(k,id);
376 }
377 else if(tree[id][k].addv)
378 {
379 tree[id][2*k+1].addv += tree[id][k].addv;
380 tree[id][2*k+2].addv += tree[id][k].addv;
381 tree[id][k].sum += (mm-nn+1)*tree[id][k].addv;
382 tree[id][k].maxx += tree[id][k].addv;
383 tree[id][k].minn += tree[id][k].addv;
384 tree[id][k].addv = 0; update(k,id);
385 }
386 //update(k,id);
387 return tree[id][k].maxx;
388 }
389 else
390 {
391 if(tree[id][k].setv)
392 {
393 tree[id][2*k+1].setv = tree[id][k].setv;
394 tree[id][2*k+2].setv = tree[id][k].setv;
395 tree[id][2*k+1].addv = tree[id][k].addv;
396 tree[id][2*k+2].addv = tree[id][k].addv;
397 tree[id][k].setv = 0;
398 tree[id][k].addv = 0;
399 }
400 else if(tree[id][k].addv)
401 {
402 tree[id][2*k+1].addv += tree[id][k].addv ;
403 tree[id][2*k+2].addv += tree[id][k].addv;
404 tree[id][k].addv = 0;
405 }
406 int nx = askmaxx(l,r,2*k+1,nn,(nn+mm)/2,id);
407 int ny = askmaxx(l,r,2*k+2,(nn+mm)/2+1,mm,id);
408 return max(nx,ny);
409 }
410 }

Fast Matrix Operations(UVA)11992的更多相关文章

  1. Fast Matrix Operations UVA - 11992 线段树

    题意翻译 有一个r行c列的全0矩阵,有以下三种操作. 1 X1 Y1 X2 Y2 v 子矩阵(X1,Y1,X2,Y2)的元素加v 2 X1 Y1 X2 Y2 v 子矩阵(X1,Y1,X2,Y2)的元素 ...

  2. UVA 11992 - Fast Matrix Operations(段树)

    UVA 11992 - Fast Matrix Operations 题目链接 题意:给定一个矩阵,3种操作,在一个矩阵中加入值a,设置值a.查询和 思路:因为最多20列,所以全然能够当作20个线段树 ...

  3. uva 11992 Fast Matrix Operations 线段树模板

    注意 setsetset 和 addvaddvaddv 标记的下传. 我们可以控制懒惰标记的优先级. 由于 setsetset 操作的优先级高于 addaddadd 操作,当下传 setsetset ...

  4. Fast Matrix Operations

    A Simple Problem with Integers 每次将区间向下更新,或是用之前的方法,统计当前节点到父节点处的覆盖数目. #include <cstdio> #include ...

  5. UVA11992 - Fast Matrix Operations(段树部分的变化)

    UVA11992 - Fast Matrix Operations(线段树区间改动) 题目链接 题目大意:给你个r*c的矩阵,初始化为0. 然后给你三种操作: 1 x1, y1, x2, y2, v ...

  6. UVA 11992 Fast Matrix Operations(线段树:区间修改)

    题目链接 2015-10-30 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=s ...

  7. 线段树(多维+双成段更新) UVA 11992 Fast Matrix Operations

    题目传送门 题意:训练指南P207 分析:因为矩阵不超过20行,所以可以建20条线段的线段树,支持两个区间更新以及区间查询. #include <bits/stdc++.h> using ...

  8. UVA 11992 Fast Matrix Operations (二维线段树)

    解法:因为至多20行,所以至多建20棵线段树,每行建一个.具体实现如下,有些复杂,慢慢看吧. #include <iostream> #include <cstdio> #in ...

  9. UVa 11992 (线段树 区间修改) Fast Matrix Operations

    比较综合的一道题目. 二维的线段树,支持区间的add和set操作,然后询问子矩阵的sum,min,max 写完这道题也是醉醉哒,代码仓库里还有一份代码就是在query的过程中也pushdown向下传递 ...

随机推荐

  1. 去空格及换行制表符【c#】

    string returnStr = tbxContractNO.Text.Replace("\n", "").Replace(" ", & ...

  2. C语言中的指针的小标可以是负数

    首先,创建一个正常的数组 int A[20];.然后用指针指向其中间的元素 int *A2 = &(A[10]); 这样,A2[-10 ... 9] 就是一个可用的有效范围了. 1 2 3 4 ...

  3. Hadoop【MR开发规范、序列化】

    Hadoop[MR开发规范.序列化] 目录 Hadoop[MR开发规范.序列化] 一.MapReduce编程规范 1.Mapper阶段 2.Reducer阶段 3.Driver阶段 二.WordCou ...

  4. Oracle中常用的系统表

    1.dba开头的表 dba_users 数据库用户信息 dba_segments 表段信息 dba_extents 数据区信息 dba_objects 数据库对象信息 dba_tablespaces ...

  5. window ntp服务

    一.确定服务端和客户端处于同一网段,能相互 Ping 通. 二.服务器端(Server)配置 1.选择一台服务器(Windows 系统)作为时间同步服务器: 2.Win + R (运行 cmd 命令行 ...

  6. Spring标签库

    spring提供了两个标签库文件:spring-form.tld(表单标签库,用于输出HTML表单)  spring.tld(基础标签库,用于Spring数据绑定等) 使用步骤: 1,配置表单标签库, ...

  7. Zookeeper客户端链接

    一.zkCli.sh ./zkCli.sh -server 39.97.176.160:2182 39.97.176.160 : zookeeper服务器Ip 2182:zookeeper端口 二.Z ...

  8. 使用fastDFS上传和下载图片文件

    package com.xuecheng.test.fastdfs;import org.csource.common.MyException;import org.csource.fastdfs.* ...

  9. Springboot集成velocity

    1.加入maven包 <parent> <groupId>org.springframework.boot</groupId> <artifactId> ...

  10. 【保姆级教程】Ubuntu18.04+Geforce 980Ti+安装CUDA10.2+Cudnn

    首先感谢师兄的博客!前半部分按照这个照做没有问题! https://www.bilibili.com/read/cv9162965/ 第一步:下载CUDA 在官网下载,查询自己的GPU型号对应的CUD ...