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. MySQL 的查询优化

    说起 MySQL 的查询优化,相信大家收藏了一堆奇技淫巧:不能使用 SELECT *.不使用 NULL 字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解它背 ...

  2. Spark(十一)【SparkSQL的基本使用】

    目录 一. SparkSQL简介 二. 数据模型 三. SparkSQL核心编程 1. IDEA开发SparkSQL 2. SparkSession 创建 关闭 获取SparkContext 3. D ...

  3. 从jvm字节码指令看i=i++和i=++i的区别

    1. 场景的产生 先来看下下面代码展示的两个场景 @Testvoid testIPP() { int i = 0; for (int j = 0; j < 10; j++) { i = i++; ...

  4. VFL

    VFL 1. 概念 VFL全称是Visual Format Language,翻译过来是"可视化格式语言" VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言 2. ...

  5. 编译安装nginx 1.16

    准备源码包,并解压,创建nginx用户 [root@slave-master ~]# tar xf nginx-1.16.0.tar.gz [root@slave-master ~]# useradd ...

  6. NoSQL之Redis学习笔记

    一.NoSQL与Redis 1.什么是NoSQL? NoSQL=Not Only SQL ,泛指非关系型数据库.随着互联网的兴起,传统的关系型数据库已经暴露了很多问题,NoSQL数据库的产生就是为了解 ...

  7. 【JS】枚举类型

    https://zhuanlan.zhihu.com/p/79137838 相当于用数字来代替一串字母 /** * 时间:2019年8月18日 * 前端教程: https://www.pipipi.n ...

  8. Snort 入侵检测系统

    Snort 入侵检测系统 一.实验目的 1.掌握snort IDS工作原理 2.应用snort 三种方式工作 二.实验环境 系统环境:Windows环境, kali环境 三.实验原理 1.snort ...

  9. [BUUCTF]PWN5——ciscn_2019_n_1

    [BUUCTF]PWN5--ciscn_2019_n_1 题目网址:https://buuoj.cn/challenges#ciscn_2019_n_1 步骤: 例行检查,64位,开启了nx保护 nc ...

  10. HMS Core版本发布公告

    新增动作捕捉能力.通过简单拍摄即可获得人体3D骨骼关键点数据,广泛应用于虚拟形象.体育运动和医学分析等场景: 3D物体建模能力iOS版本上线. 查看详情>> 新增道路吸附能力.可根据坐标点 ...