题目传送门

题意:训练指南P207

分析:因为矩阵不超过20行,所以可以建20条线段的线段树,支持两个区间更新以及区间查询.

#include <bits/stdc++.h>
using namespace std; #define lson l, mid, o << 1
#define rson mid + 1, r, o << 1 | 1
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 20 + 5;
const int M = 5e4 + 5;
struct Segment_Tree {
struct Node {
int sum, mx, mn, add, setv;
}node[M<<2];
void _max(int &a, int b) {
if (a < b) a = b;
}
void _min(int &a, int b) {
if (a > b) a = b;
}
void push_up(int o) {
node[o].sum = node[o<<1].sum + node[o<<1|1].sum;
node[o].mx = max (node[o<<1].mx, node[o<<1|1].mx);
node[o].mn = min (node[o<<1].mn, node[o<<1|1].mn);
}
void push_down(int l, int r, int o) {
int len = r - l + 1;
if (node[o].setv != -1 && l < r) { //先set,然后再add
node[o<<1].setv = node[o<<1|1].setv = node[o].setv;
node[o<<1].add = node[o<<1|1].add = 0; //很重要的地方,有set的清除add,意思是set前的add都不要了
node[o<<1].sum = node[o].setv * (len - (len >> 1));
node[o<<1].mx = node[o<<1].mn = node[o].setv;
node[o<<1|1].sum = node[o].setv * (len >> 1);
node[o<<1|1].mx = node[o<<1|1].mn = node[o].setv;
node[o].setv = -1;
}
if (node[o].add != 0 && l < r) {
node[o<<1].add += node[o].add; node[o<<1|1].add += node[o].add;
node[o<<1].sum += node[o].add * (len - (len >> 1));
node[o<<1].mx += node[o].add; node[o<<1].mn += node[o].add;
node[o<<1|1].sum += node[o].add * (len >> 1);
node[o<<1|1].mx += node[o].add; node[o<<1|1].mn += node[o].add;
node[o].add = 0;
}
}
void build(int l, int r, int o) {
node[o].add = 0; node[o].setv = -1;
if (l == r) {
node[o].sum = 0; node[o].mx = 0; node[o].mn = 0;
return ;
}
int mid = l + r >> 1;
build (lson); build (rson);
push_up (o);
}
void updata(int ql, int qr, int op, int c, int l, int r, int o) {
if (ql <= l && r <= qr) {
if (op == 1) {
node[o].sum += c * (r - l + 1); node[o].mx += c; node[o].mn += c;
node[o].add += c; return ;
}
else if (op == 2) {
node[o].sum = c * (r - l + 1); node[o].mx = node[o].mn = c;
node[o].add = 0;
node[o].setv = c; return ;
}
}
push_down (l, r, o);
int mid = l + r >> 1;
if (ql <= mid) updata (ql, qr, op, c, lson);
if (qr > mid) updata (ql, qr, op, c, rson);
push_up (o);
}
void query(int ql, int qr, int &_sum, int &_mn, int &_mx, int l, int r, int o) {
if (ql <= l && r <= qr) {
_sum += node[o].sum;
_max (_mx, node[o].mx);
_min (_mn, node[o].mn);
return ;
}
push_down (l, r, o);
int mid = l + r >> 1;
if (ql <= mid) query (ql, qr, _sum, _mn, _mx, lson);
if (qr > mid) query (ql, qr, _sum, _mn, _mx, rson);
}
}st[N];
int n, m, q; int main(void) {
while (scanf ("%d%d%d", &n, &m, &q) == 3) {
for (int i=1; i<=n; ++i) {
st[i].build (1, m, 1);
}
int x1, y1, x2, y2, v, op;
while (q--) {
scanf ("%d%d%d%d%d", &op, &x1, &y1, &x2, &y2);
if (op <= 2) {
scanf ("%d", &v);
for (int i=x1; i<=x2; ++i) {
st[i].updata (y1, y2, op, v, 1, m, 1);
}
}
else {
int sum = 0, mx = 0, mn = INF;
for (int i=x1; i<=x2; ++i) {
st[i].query (y1, y2, sum, mn, mx, 1, m, 1);
}
printf ("%d %d %d\n", sum, mn, mx);
}
}
} return 0;
}

  

线段树(多维+双成段更新) UVA 11992 Fast Matrix Operations的更多相关文章

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

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

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

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

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

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

  4. UVA 11992 Fast Matrix Operations(线段树:区间修改)

    题目链接 2015-10-30 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=s ...

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

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

  6. 【UVA】11992 - Fast Matrix Operations(段树模板)

    主体段树,要注意,因为有set和add操作,当慵懒的标志下推.递归优先set,后复发add,每次运行set行动add马克清0 WA了好几次是由于计算那一段的时候出问题了,可笑的是我对着模板找了一个多小 ...

  7. POJ 2155 Matrix (二维线段树入门,成段更新,单点查询 / 二维树状数组,区间更新,单点查询)

    题意: 有一个n*n的矩阵,初始化全部为0.有2中操作: 1.给一个子矩阵,将这个子矩阵里面所有的0变成1,1变成0:2.询问某点的值 方法一:二维线段树 参考链接: http://blog.csdn ...

  8. ACM: Copying Data 线段树-成段更新-解题报告

    Copying Data Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description W ...

  9. HDU 1698 Just a Hook(线段树成段更新)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

随机推荐

  1. IOS- 单例

    单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 1.单例模式的要点: 显然单例模式的要点有三个:一是某个类只能有一个实例: ...

  2. xmpp SASL 定义

    SASL 定义 <摘抄自:xmpp_3920> [SASL]的 profiling 需求要求协议定义 供以下信息: 服务名:“xmpp” 初始序列:初始实体 供一个开放 XML 流头后,并 ...

  3. 宠物收养所(bzoj1208)

    Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特 ...

  4. SOCKet 编程 简介

    “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. ——有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览 ...

  5. C#4.0图解教程 - 第24章 反射和特性 – 2.特性

    1.特性 定义 Attribute用来对类.属性.方法等标注额外的信息,贴一个标签(附着物) 通俗:给 类 或 类成员 贴一个标签,就像航空部为你的行李贴一个标签一样 注意,特性 是 类 和 类的成员 ...

  6. Myeclipse 2016 & 2014 下载

    myeclipse-2016-ci-6-offline-installer-windowshttps://downloads.genuitec.com/downloads/myeclipse/inst ...

  7. Oracle如何写出高效的SQL

    转载:http://www.blogjava.net/ashutc/archive/2009/07/19/277215.html 1.选择最有效率的表明顺序(只在基于规则的优化器中有效) Oracle ...

  8. 【Agorithm】一次一密加密解密算法

    #include<iostream> #include<cstdio> #include<cstdlib> #include<ctime> #inclu ...

  9. Introduction to replication 翻译

    翻译自用,还有很多谬误之处,敬请甄别,转载请注明出处 Introduction to replication (replication介绍)   Replication is one of the m ...

  10. WIN10 新建ORACLE实例

    1 管理员身份进入CMD环境,执行DBCA命令,在弹出窗口的引导中,完成实例创建 2 如果在创建过程中没有选择适当的字符集(最好采用默认字符集),如下图所示,在进入PLSQL DEVELOPER的时候 ...