UVA 11992 Fast Matrix Operations(线段树:区间修改)
题目链接 2015-10-30 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3143
给你一个矩阵,矩阵的每个元素初始值均为0
进行m次操作,操作共有三种类型,分别用1,2,3表示
操作一:子矩阵(x1, y1, x2, y2)的所有元素增加v
操作二:子矩阵(x1, y1, x2, y2)的所有元素设为v
操作三:查询子矩阵(x1, y1, x2, y2)的元素和,最小值和最大值
矩阵只有20行,可以每行建一棵线段树(建议直接转为一维)
#include <iostream>
#include <cstring>
#include <algorithm>
#define maxn 3000100
#define inf 1000000000
#define LL(x) x<<1
#define RR(x) x<<1|1
using namespace std; typedef long long LL; //variable define struct tree
{
int l, r;
int mi, ma, sum;
int add, set;
}; tree node[maxn];
int row, col, m, ans_mi, ans_ma, ans_sum; //function define void push_down(int x); void push_up(int x); void build_tree(int left, int right, int x); void query(int left, int right, int x); void update_set(int left, int right, int x, int val); void update_add(int left, int right, int x, int val); int main(void)
{
while (scanf("%d %d %d", &row, &col, &m) != EOF)
{
build_tree( , row*col, );
int op, x1, y1, x2, y2, val;
while (m--)
{
scanf("%d", &op);
if (op == )
{
scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &val);
for (int i = x1; i <= x2; ++i)
update_add( (i-)*col + y1, (i-)*col + y2, , val);
}
else if (op == )
{
scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &val);
for (int i = x1; i <= x2; ++i)
update_set( (i-)*col + y1, (i-)*col + y2, , val);
}
else
{
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
ans_sum = ;
ans_ma = -inf;
ans_mi = inf;
for (int i = x1; i <= x2; ++i)
query( (i-)*col + y1, (i-)*col + y2, );
//output
printf("%d %d %d\n", ans_sum, ans_mi, ans_ma);
}
}
}
return ;
} void build_tree(int left, int right, int x)
{
node[x].l = left;
node[x].r = right;
node[x].ma = node[x].mi = node[x].sum = ;
node[x].add = ;
node[x].set = -; if (left == right)
return; int lx = LL(x);
int rx = RR(x);
int mid = left + (right - left)/;
build_tree(left, mid, lx);
build_tree(mid + , right, rx);
//push_up(x);
} void push_up(int x)
{
if (node[x].l >= node[x].r)
return; int lx = LL(x);
int rx = RR(x);
node[x].ma = max( node[lx].ma, node[rx].ma);
node[x].mi = min( node[lx].mi, node[rx].mi);
node[x].sum = node[lx].sum + node[rx].sum;
} void push_down(int x)
{
if (node[x].l >= node[x].r)
return;
int lx = LL(x);
int rx = RR(x);
if (node[x].set != -)
{
node[lx].set = node[rx].set = node[x].set;
node[lx].mi = node[rx].mi = node[x].set;
node[lx].ma = node[rx].ma = node[x].set;
node[lx].add = node[rx].add = ;
node[lx].sum = (node[lx].r - node[lx].l + ) * node[x].set;
node[rx].sum = (node[rx].r - node[rx].l + ) * node[x].set;
}
if (node[x].add > )
{
LL tmp = node[x].add;
node[lx].add += tmp;
node[rx].add += tmp;
node[lx].ma += tmp;
node[rx].ma += tmp;
node[lx].mi += tmp;
node[rx].mi += tmp;
node[lx].sum += (tmp * (node[lx].r - node[lx].l + ));
node[rx].sum += (tmp * (node[rx].r - node[rx].l + ));
}
} void update_set(int left, int right, int x, int val)
{
if (node[x].l == left && node[x].r == right)
{
node[x].set = val;
node[x].ma = node[x].mi = val;
node[x].sum = (right - left + ) * val;
node[x].add = ;
return;
}
push_down(x);
node[x].set = -;
node[x].add = ;
int lx = LL(x);
int rx = RR(x);
int mid = node[x].l + (node[x].r - node[x].l)/;
if (right <= mid)
update_set(left, right, lx, val);
else if (left > mid)
update_set(left, right, rx, val);
else
{
update_set(left, mid, lx, val);
update_set(mid + , right, rx, val);
}
push_up( x);
} void update_add(int left, int right, int x, int val)
{
if (node[x].l == left && node[x].r == right)
{
node[x].add += val;
node[x].ma += val;
node[x].mi += val;
node[x].sum += (node[x].r - node[x].l + ) * val;
return;
}
push_down( x);
node[x].set = -;
node[x].add = ;
int lx = LL(x);
int rx = RR(x);
int mid = node[x].l + (node[x].r - node[x].l)/; if (right <= mid)
update_add(left, right, lx, val);
else if (left > mid)
update_add(left, right, rx, val);
else
{
update_add(left, mid, lx, val);
update_add(mid + , right, rx, val);
}
push_up(x);
} void query(int left, int right, int x)
{
if (node[x].l == left && node[x].r == right)
{
ans_sum += node[x].sum;
ans_ma = max( ans_ma, node[x].ma);
ans_mi = min( ans_mi, node[x].mi);
return;
}
push_down(x);
node[x].set = -;
node[x].add = ;
int mid = node[x].l + (node[x].r - node[x].l)/;
int lx = LL(x);
int rx = RR(x);
if (right <= mid)
query(left, right, lx);
else if (left > mid)
query(left, right, rx);
else
{
query(left, mid, lx);
query(mid + , right, rx);
}
push_up(x);
}
UVA 11992 Fast Matrix Operations(线段树:区间修改)的更多相关文章
- uva 11992 Fast Matrix Operations 线段树模板
注意 setsetset 和 addvaddvaddv 标记的下传. 我们可以控制懒惰标记的优先级. 由于 setsetset 操作的优先级高于 addaddadd 操作,当下传 setsetset ...
- UVA 11992 - Fast Matrix Operations(段树)
UVA 11992 - Fast Matrix Operations 题目链接 题意:给定一个矩阵,3种操作,在一个矩阵中加入值a,设置值a.查询和 思路:因为最多20列,所以全然能够当作20个线段树 ...
- UVa 11992 Fast Matrix Operations (线段树,区间修改)
题意:给出一个row*col的全0矩阵,有三种操作 1 x1 y1 x2 y2 v:将x1 <= row <= x2, y1 <= col <= y2里面的点全部增加v: 2 ...
- 线段树(多维+双成段更新) UVA 11992 Fast Matrix Operations
题目传送门 题意:训练指南P207 分析:因为矩阵不超过20行,所以可以建20条线段的线段树,支持两个区间更新以及区间查询. #include <bits/stdc++.h> using ...
- UVA 11992 Fast Matrix Operations (二维线段树)
解法:因为至多20行,所以至多建20棵线段树,每行建一个.具体实现如下,有些复杂,慢慢看吧. #include <iostream> #include <cstdio> #in ...
- uva 11992 - Fast Matrix Operations
简单的线段树的题: 有两种方法写这个题,目前用的熟是这种慢点的: 不过不知道怎么老是T: 感觉网上A过的人的时间度都好小,但他们都是用数组实现的 难道是指针比数组慢? 好吧,以后多用数组写写吧! 超时 ...
- UVA 11992 Fast Matrix Operations (降维)
题意:对一个矩阵进行子矩阵操作. 元素最多有1e6个,树套树不好开(我不会),把二维坐标化成一维的,一个子矩阵操作分解成多条线段的操作. 一次操作的复杂度是RlogC,很容易找到极端的数据(OJ上实测 ...
- UVA11992 - Fast Matrix Operations(段树部分的变化)
UVA11992 - Fast Matrix Operations(线段树区间改动) 题目链接 题目大意:给你个r*c的矩阵,初始化为0. 然后给你三种操作: 1 x1, y1, x2, y2, v ...
- 题解报告:hdu 1698 Just a Hook(线段树区间修改+lazy懒标记的运用)
Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for m ...
随机推荐
- 【转】Using Gamma 2.2
This is a detailed description of the work with Gamma 2.2. If you are only interested in exact instr ...
- Inside The C++ Object Model - 01
前言 1.Foundation项目是一个定义大系统开发模型的项目,又叫Grail. 2.Grail中编译器被分为:parser(语法分析)->type checking -> simpli ...
- 44. 普通对象建一个用户方法,提交时报:失败:建立业务逻辑对象失败:业务逻辑定义更新到数据库失败:ORA-00904: "DEFVERSION": 标识符无效
LBBIZPROCESSDEFSLBHISTORYBIZPROCESSDEFSLBHISTORYMULTIWFDEFSDESIGNLBHISTORYWORKFLOWDEFSDESIGNLBMULTIW ...
- pgadmin中的备份功能消失的原因和找回方法
pgadmin在正常情况下,在左侧的[对象浏览器]中选中数据库.模式或者表时,右键会出现[备份]和[恢复]的选项(除早期不支持该功能的版本外). 如: 当然,有时候有人会发现,当你想要用这些备份还原功 ...
- mysql 主从复制 实践
异步主从复制 主从部署步骤: 备份还原 使用mysqldump或者xtrabackup 把主库现有基础数据还原到从库 授权 grant replication slave on *.* 给从库一个 ...
- Repeater控件 ---属性(ItemCommand事件)
epeater的Command操作:1.ItemCommand事件 - 在Repeater中所有能触发事件的控件,都会来触发这一个事件 2.CommandName - 判断点击的是什么按钮,e.Com ...
- VC++ 浅谈VS2010中CMFCToolBar的用法
本文将给大家介绍Visual Studio 2010中CMFCToolBar的用法,CMFCToolBar可以让用户自定义工具栏图标,使用静态成员函数SetUserImages()将一个CMFCToo ...
- Ruby-Array数组
1.创建数组 a=Array.new(6,obj=nil) #=> [nil, nil, nil, nil, nil, nil] 设置默认值 a=Array.new(6) ...
- java基础十一[远程部署的RMI](阅读Head First Java记录)
方法的调用都是发生在相同堆上的两个对象之间(同一台机器的Java虚拟机),如果想要调用另一台机器上的对象,可以通过Socket进行输入/输出. 远程过程调用需要创建出4种东西:服务器.客户端.服务器辅 ...
- NDK相关以及同步相关博客收集
http://www.cnblogs.com/heiing/archive/2013/01/20/2868268.htmlhttp://blog.sina.com.cn/s/blog_461c24d5 ...