[uva11992]Fast Matrix Operations(多延迟标记,二维线段树,区间更新)
题目链接: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 ...
随机推荐
- Android -- 仿小红书欢迎界面
1,觉得小红书的欢迎界面感觉很漂亮,就像来学习学习一下来实现类似于这种效果 原效果图如下: 2,根据效果我们来一点点分析 第一步:首先看一下我们的主界面布局文件视图效果如下: main_activi ...
- YIi2 Pjax简单使用
1.点击事件需要在Pjax::begin() 和Pjax::end()范围内 2.需要在链接配置数组后加上 ['data-pjax'=>'#testPjax'] 其中,'#testPjax‘是 ...
- QQ好友在线/离线,怎么测试?
即时通讯是目前internet上最为流行的通讯方式,各种各样的即时通讯软件也层出不穷,那么今天主要针对QQ好友在线状态/QQ群友在线状态功能出发,一起思考其中的实现原理以及我们如何去测试此功能? 当大 ...
- Redhat
vm1 port:192.168.210.102 user:root;pwd:123456 user:openflowpwd:openflowKkm09!q esx4.1 server 安装一.修改I ...
- 整理:20个非常有用的Java程序片段
下面是20个非常有用的Java程序片段,希望能对你有用. 1. 字符串有整型的相互转换 String a = String.valueOf(2); //integer to numeric strin ...
- Java程序中与MongoDB建立连接~小记
1.Mongo和MongoClient的关系 MongoClient继承自Mongo,使用Mongo也可建立连接,但是需要使用与Mongo适应的MongoOptions,MongoURI等类型. 2. ...
- 请一定记得升级java虚拟机
对于吃货出身又需要保持体重的我,出门一定要带男票,因为这样就可以把见到的好吃的都买给他吃,就当是自己吃了[汗].偶尔做梦还是会梦到自己一个角落里偷吃东西,听到有脚步声,抬起头,大哭起来:“我饿了.” ...
- 使用 ipdb 调试 Python
1.安装 pip install ipdb 2.使用 python -m ipdb xxx.py 程序内部: from ipdb import set_trace set_trace() 3.常用命令 ...
- Unity 3D Framework Designing(7)——IoC工厂理念先行
一谈到 『IoC』,有经验的程序员马上会联想到控制反转,将创建对象的责任反转给工厂.IoC是依赖注入 『DI』 的核心,大名鼎鼎的Spring框架就是一个非常卓越的的控制反转.依赖注入框架.遗憾的是, ...
- Linux 和 Windows 下实现多进程的方式以及管道操作
一.多进程 1.windows 多进程 使用 #include<windows.h> 下面的 BOOL CreateProcess( LPCWSTR pszImageName, LPCWS ...