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 ...
随机推荐
- click事件
click事件是可以多次绑定的,如果绑定多次就会执行多次,因此再不需要重复执行的情况下,就需要使用unbind对事件进行解绑
- C++ 如何有效地使用对话框
Q:如何在对话框中加入工具条 在 OnInitDialog 中加入下面代码: BOOL CYourDlg::OnInitDialog() { CDialog::OnInitDialog(); // C ...
- ReSharper 文件注释
添加文件注释方法如下: 打开菜单RESHARPER->Options->Code Editing –> File Header Text 如图所示,在其中空白处添加对应文件头注释, ...
- loadrunner 联机跑负载 win server 2012 r2环境部署
下列为在实际loadrunner 联机跑负载 win server 2012 r2环境部署中进行的成功案例,遇到的问题和解决方法,仅作整理和记录,如转载请署名及原文地址. ps:欢迎加q群872584 ...
- flex polygon 序列化为txt 文本
当我们要把一个地块导出为txt的时候,应该怎么写,这是比较有用的这样可以帮助我们存档之类的,这里是基于某个地方的独立坐标系,是基于自己发布地图,如果是用百度地图或者其他网上的地图可能不适用. pack ...
- 在silverlight中通过WCF连接ORACLE DB数据库(转)
转自 http://hi.baidu.com/qianlihanse/item/458aa7c8d93d4e0cac092ff4 这不是我的原创,我也是上网学习的~ How to get data f ...
- 苹果刷机相关开源代码(如iRecovery等)收集汇总(不断更新中...)
下面截图是在下面开源代码下使用VS2015修改部分代码后适配而成,可以在Windows平台上运行, 下载连接: http://pan.baidu.com/s/1i4zKGx3.
- NHibernate系列文章十六:使用程序集管理NHibernate项目(附程序下载)
摘要 在实际的项目中,经常是将NHibernate的实体关系映射类做成独立的工程(assembly dll),只对外提供Session调用的接口.这个程序集作为数据访问层,可以被上面的多个工程(ASP ...
- 3D图形学常用公式
本篇内容来自于书籍<3D图形学基础:图形与游戏开发>,个人总结 1.数学背景与历史 笛卡尔数学由著名的法国哲学家.物理学家.生物学家.数学家"勒奈·笛卡尔"发明. 1. ...
- javaweb学习第一天 debug
debug 断点: f5:step into f6:step over f7:step return drop to frame:跳到当前方法的的第一行 resume:跳到下一个断点 watch:观察 ...