题目链接 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(线段树:区间修改)的更多相关文章

  1. uva 11992 Fast Matrix Operations 线段树模板

    注意 setsetset 和 addvaddvaddv 标记的下传. 我们可以控制懒惰标记的优先级. 由于 setsetset 操作的优先级高于 addaddadd 操作,当下传 setsetset ...

  2. UVA 11992 - Fast Matrix Operations(段树)

    UVA 11992 - Fast Matrix Operations 题目链接 题意:给定一个矩阵,3种操作,在一个矩阵中加入值a,设置值a.查询和 思路:因为最多20列,所以全然能够当作20个线段树 ...

  3. UVa 11992 Fast Matrix Operations (线段树,区间修改)

    题意:给出一个row*col的全0矩阵,有三种操作 1 x1 y1 x2 y2 v:将x1 <= row <= x2, y1 <= col <= y2里面的点全部增加v: 2 ...

  4. 线段树(多维+双成段更新) UVA 11992 Fast Matrix Operations

    题目传送门 题意:训练指南P207 分析:因为矩阵不超过20行,所以可以建20条线段的线段树,支持两个区间更新以及区间查询. #include <bits/stdc++.h> using ...

  5. UVA 11992 Fast Matrix Operations (二维线段树)

    解法:因为至多20行,所以至多建20棵线段树,每行建一个.具体实现如下,有些复杂,慢慢看吧. #include <iostream> #include <cstdio> #in ...

  6. uva 11992 - Fast Matrix Operations

    简单的线段树的题: 有两种方法写这个题,目前用的熟是这种慢点的: 不过不知道怎么老是T: 感觉网上A过的人的时间度都好小,但他们都是用数组实现的 难道是指针比数组慢? 好吧,以后多用数组写写吧! 超时 ...

  7. UVA 11992 Fast Matrix Operations (降维)

    题意:对一个矩阵进行子矩阵操作. 元素最多有1e6个,树套树不好开(我不会),把二维坐标化成一维的,一个子矩阵操作分解成多条线段的操作. 一次操作的复杂度是RlogC,很容易找到极端的数据(OJ上实测 ...

  8. UVA11992 - Fast Matrix Operations(段树部分的变化)

    UVA11992 - Fast Matrix Operations(线段树区间改动) 题目链接 题目大意:给你个r*c的矩阵,初始化为0. 然后给你三种操作: 1 x1, y1, x2, y2, v ...

  9. 题解报告: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 ...

随机推荐

  1. attr与prop

    Jquery获取checkbox属性checked为undefined (-- ::)转载▼ 标签: js jquery checkbox checked undefined 分类: JQuery 使 ...

  2. 第一零三天上课 PHP TP框架下控制器的方法分离

    (1)配置信息 修改配置文件->Config.php (配置后,原先的控制方法无效) 'ACTION_BIND_CLASS' => TRUE, // 控制器方法分离 (2)在Control ...

  3. maven 加入本地jar包

    Apache Maven,由Apache软件基金会所提供.基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建.报告和文档等步骤.曾是Jakarta项目的子项目,现 ...

  4. LinQ 高级查询

    高级查询 模糊查(包含):.Contains(name) 开头:.StartsWith(name) 结尾:.EndsWith(name) 个数:.Count() 最大值:Max(r => r.p ...

  5. LZW压缩算法

    转载自http://www.cnblogs.com/jillzhang/archive/2006/11/06/551298.html 记录此处仅自己供学习之用 lzw解压缩算法: 用单个字符初始化字符 ...

  6. 2015年毕业生收到的offer和薪资透露

    个人情况:全国排名70多的大学,非211,计算机专业硕士 收到的offer: 苏州同程旅游--6k/月 ,自己要了这么多,就给了这么多,没有规范.苏州蜗牛科技--8k/月 ,给了个口头offer,要去 ...

  7. confirm确认对话框

    还记得之前的javascript入门里的讲的confirm 消息对话框吗?不记得也没关系,我们先来回顾一下,然后在详细讲它. 复习: confirm 消息对话框通常用于允许用户做选择的动作,如:“你对 ...

  8. Elasticsearch refresh vs. flush【转载】

    源地址:    http://www.jianshu.com/p/0e9f6346f1fe 问: 若一个新的文档索引进ES索引,则它在索引操作执行后约1s可以搜索到.然而我们可以直接调用_flush或 ...

  9. Python全栈--7.3--模块补充configparser--logging--subprocess--os.system--shutil

    模块补充: 一.configparser用于处理特定格式的文件,其本质是利用open来操作文件 继承到2版本 configparser 实现了更多智能特征,更有壳预见性,新的应用更偏好这个版本, 处理 ...

  10. 第三十九章 微服务CICD(1)- gitlab搭建与使用(docker版)

    一.下载docker镜像 前提:docker引擎已经安装好. docker pull gitlab/gitlab-ce gitlab是8.13.1版本. 二.启动应用 docker run -d -h ...