题目链接:https://vjudge.net/problem/UVA-11992
题意:n*m的矩阵,每次对一个子矩阵操作,有三种操作:加x,设置为x,查询。查询返回子矩阵和、最小值、最大值
n很小(<=20),所以可以开20棵线段树,每次操作按行更新。
特别小心put和add两个延迟标记,坑老惨了。
put初始化-1最简单的坑,略过。
build的时候要每一个节点都要clear,不能只clear叶子。因为会有直接差没操作的子矩阵(因为初始化都是0)。
数组开大。。。
add的话,什么都不用管。
put的话,在update的时候要把那时候的add标记清空,不要忘记在向下传递的时候,也要清空!
上述几点都注意到,这题就能A。感觉写了一道模拟题。
#include <bits/stdc++.h>
using namespace std; #define lrt rt << 1
#define rrt rt << 1 | 1
typedef struct Node {
int lo, hi, sum;
int add, put;
}Node;
const int maxn = ;
const int maxm = ;
Node seg[maxn][maxm<<];
int n, m, q; void pushup(Node* seg, int rt) {
seg[rt].sum = seg[lrt].sum + seg[rrt].sum;
seg[rt].lo = min(seg[lrt].lo, seg[rrt].lo);
seg[rt].hi = max(seg[lrt].hi, seg[rrt].hi);
} void pushdown(Node* seg, int rt, int l, int r) {
int mid = (l + r) >> ;
if(seg[rt].put != -) {
seg[lrt].sum = (mid - l + ) * seg[rt].put;
seg[rrt].sum = (r - mid) * seg[rt].put;
seg[lrt].lo = seg[lrt].hi = seg[rt].put;
seg[rrt].lo = seg[rrt].hi = seg[rt].put;
seg[lrt].put = seg[rrt].put = seg[rt].put;
seg[lrt].add = seg[rrt].add = ;
seg[rt].put = -;
}
if(seg[rt].add) {
seg[lrt].sum += (mid - l + ) * seg[rt].add;
seg[rrt].sum += (r - mid) * seg[rt].add;
seg[lrt].lo += seg[rt].add;
seg[lrt].hi += seg[rt].add;
seg[rrt].lo += seg[rt].add;
seg[rrt].hi += seg[rt].add;
seg[lrt].add += seg[rt].add;
seg[rrt].add += seg[rt].add;
seg[rt].add = ;
}
} void build(Node* seg, int l, int r, int rt) {
seg[rt].lo = seg[rt].hi = seg[rt].sum = seg[rt].add = ;
seg[rt].put = -;
if(l == r) return;
int mid = (l + r) >> ;
build(seg, l, mid, lrt);
build(seg, mid+, r, rrt);
} void update(Node* seg, int L, int R, int l, int r, int rt, int val, int type) {
if(L <= l && r <= R) {
if(type == ) {
seg[rt].lo += val;
seg[rt].hi += val;
seg[rt].add += val;
seg[rt].sum += (r - l + ) * val;
}
else if(type == ) {
seg[rt].lo = val;
seg[rt].hi = val;
seg[rt].put = val;
seg[rt].sum = (r - l + ) * val;
seg[rt].add = ;
}
return;
}
pushdown(seg, rt, l, r);
int mid = (l + r) >> ;
if(L <= mid) update(seg, L, R, l, mid, lrt, val, type);
if(mid < R) update(seg, L, R, mid+, r, rrt, val, type);
pushup(seg, rt);
} Node query(Node* seg, int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) return seg[rt];
pushdown(seg, rt, l, r);
int mid = (l + r) >> ;
Node ret;
ret.lo = 0x7f7f7f7f, ret.hi = , ret.sum = ;
if(L <= mid) {
Node tmp = query(seg, L, R, l, mid, lrt);
ret.lo = min(ret.lo, tmp.lo);
ret.hi = max(ret.hi, tmp.hi);
ret.sum += tmp.sum;
}
if(mid < R) {
Node tmp = query(seg, L, R, mid+, r, rrt);
ret.lo = min(ret.lo, tmp.lo);
ret.hi = max(ret.hi, tmp.hi);
ret.sum += tmp.sum;
}
pushup(seg, rt);
return ret;
} int main() {
// freopen("in", "r", stdin);
// freopen("out", "w", stdout);
int type, x1, y1, x2, y2, val;
while(~scanf("%d%d%d",&n,&m,&q)) {
for(int i = ; i <= n; i++) {
build(seg[i], , m, );
}
while(q--) {
scanf("%d%d%d%d%d",&type,&x1,&y1,&x2,&y2);
if(type == ) {
Node ret, tmp;
ret.lo = 0x7f7f7f7f, ret.hi = , ret.sum = ;
for(int i = x1; i <= x2; i++) {
tmp = query(seg[i], y1, y2, , m, );
ret.lo = min(ret.lo, tmp.lo);
ret.hi = max(ret.hi, tmp.hi);
ret.sum += tmp.sum;
}
printf("%d %d %d\n", ret.sum, ret.lo, ret.hi);
}
else {
scanf("%d", &val);
for(int i = x1; i <= x2; i++) {
update(seg[i], y1, y2, , m, , val, type);
}
}
}
}
return ;
}
[uva11992]Fast Matrix Operations(多延迟标记,二维线段树,区间更新)的更多相关文章
-
HDU 4819 Mosaic (二维线段树&;区间最值)题解
思路: 二维线段树模板题,马克一下,以后当模板用 代码: #include<cstdio> #include<cmath> #include<cstring> #i ...
-
HDU 1823 Luck and Love (二维线段树&;区间最值)题解
思路: 树套树,先维护x树,再维护y树,多练练应该就能懂了 代码: #include<cstdio> #include<cmath> #include<cstring&g ...
-
UVA11992 - Fast Matrix Operations(段树部分的变化)
UVA11992 - Fast Matrix Operations(线段树区间改动) 题目链接 题目大意:给你个r*c的矩阵,初始化为0. 然后给你三种操作: 1 x1, y1, x2, y2, v ...
-
poj 2155:Matrix(二维线段树,矩阵取反,好题)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17880 Accepted: 6709 Descripti ...
-
POJ 2155 Matrix (二维线段树)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17226 Accepted: 6461 Descripti ...
-
POJ 2155 Matrix (二维线段树入门,成段更新,单点查询 / 二维树状数组,区间更新,单点查询)
题意: 有一个n*n的矩阵,初始化全部为0.有2中操作: 1.给一个子矩阵,将这个子矩阵里面所有的0变成1,1变成0:2.询问某点的值 方法一:二维线段树 参考链接: http://blog.csdn ...
-
ZOJ 1859 Matrix Searching(二维线段树)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1859 Matrix Searching Time Limit: 10 Seco ...
-
poj 2155 matrix 二维线段树 线段树套线段树
题意 一个$n*n$矩阵,初始全为0,每次翻转一个子矩阵,然后单点查找 题解 任意一种能维护二维平面的数据结构都可以 我这里写的是二维线段树,因为四分树的写法复杂度可能会退化,因此考虑用树套树实现二维 ...
-
洛谷P3437 [POI2006]TET-Tetris 3D(二维线段树 标记永久化)
题意 题目链接 Sol 二维线段树空间复杂度是多少啊qwqqq 为啥这题全网空间都是\(n^2\)还有人硬要说是\(nlog^2n\)呀.. 对于这题来说,因为有修改操作,我们需要在外层线段树上也打标 ...
-
bzoj 1513 POI2006 Tet-Tetris 3D 二维线段树+标记永久化
1511: [POI2006]OKR-Periods of Words Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 351 Solved: 220[S ...
随机推荐
-
一个利用sed和awk处理文本的小栗子
这两天做<Linux操作系统>课程的作业,碰到了一个题目,感觉很有意思,很考验对awk掌握的熟练度,故特意拿来分享. 首先说题目是这样的,有这样一段文本: RECORD #这是多余的注释行 ...
-
20分钟入门Redux
Redux就是个数据中心,不依附于任何框架在哪使用都行.但是和它最搭配的应该就是React了,而且大家学习它的动力大多也是解决React状态管理的问题.都说Redux文档详尽清晰,但我感觉并不友好,它 ...
-
前台研发工具Sublime
沟通交流群 [极客Online : 546653637] 欢迎您! 今天一个朋友@我,问有没有好的IDE推荐一下,其实现在有很多文本工具可供选择,像Nodepad++.Editplus之类的,之前我使 ...
-
BZOJ 1020 安全的航线flight
Description 在设计航线的时候,安全是一个很重要的问题.首先,最重要的是应采取一切措施确保飞行不会发生任何事故,但同时也需要做好最坏的打算,一旦事故发生,就要确保乘客有尽量高的生还几率.当飞 ...
-
docker 安装 msyql
**************************************************************************************************** ...
-
Prometheus-自定义Node_Exporter
标量(Scalar):一个浮点型的数字值 标量只有一个数字,没有时序. 需要注意的是,当使用表达式count(http_requests_total),返回的数据类型,依然是瞬时向量.用户可以通过内置 ...
-
《Web性能权威指南》
<Web性能权威指南> 基本信息 原书名:High performance browser networking 原出版社: O'Reilly Media 作者: (加)Ilya Grig ...
-
前端学习之路之CSS (四)
Infi-chu: http://www.cnblogs.com/Infi-chu/ CSS盒子模型 概念:CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距,边框,填充,和实际 ...
-
VS code 自定义快捷输入
本文是从简书复制的, markdown语法可能有些出入, 想看"正版"和更多内容请关注 简书: 小贤笔记 位置 ctrl+shift+p 搜索: snippets 输入类型: 比如 ...
-
JavaWeb_静态导入、自动拆箱/装箱
静态导入用于简化程序对类静态属性和方法的调用. 语法 import static 包名.类名.静态属性|静态方法|* 例如 import static java.lang.System.out imp ...