解题思路:

  将矩阵每一行建立一棵线段树,进而变成一维问题求解。注意数组要开 4*N

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std;
const int maxn = + ; const int INF = ;
int q, x1_, x2_, y1, y2, v_add, v_set; struct segment_tree {
int sumv[4*maxn],minv[4*maxn],maxv[4*maxn];
int addv[4*maxn], setv[4*maxn];
void maintain(int o, int L, int R) {
int lc = *o, rc = *o + ;
sumv[o] = minv[o] = maxv[o] = ;
if(setv[o] >= ) {
sumv[o] = setv[o] * (R-L+);
minv[o] = maxv[o] = setv[o];
}
else if(R > L) {
sumv[o] = sumv[lc] + sumv[rc];
minv[o] = min(minv[lc], minv[rc]);
maxv[o] = max(maxv[lc], maxv[rc]);
}
minv[o] += addv[o]; maxv[o] += addv[o]; sumv[o] += addv[o] * (R-L+);
}
void pushdown(int o) {
int lc = *o, rc = *o+;
if(setv[o] >= ) {
setv[lc] = setv[rc] = setv[o];
addv[lc] = addv[rc] = ;
setv[o] = -;
}
if(addv[o] > ) {
addv[lc] += addv[o];
addv[rc] += addv[o];
addv[o] = ;
}
}
void update_add(int o, int L, int R) {
int lc = *o, rc = o*+;
if(y1 <= L && y2 >= R) {
addv[o] += v_add;
}
else {
pushdown(o);
int M = L + (R-L)/;
if(y1 <= M) update_add(lc, L, M); else maintain(lc, L, M);
if(y2 > M) update_add(rc, M+, R);else maintain(rc, M+, R);
}
maintain(o, L, R);
}
void update_set(int o, int L, int R) {
int lc = *o, rc = o*+;
if(y1 <= L && y2 >= R) {
setv[o] = v_set;
addv[o] = ;
}
else {
pushdown(o);
int M = L + (R-L)/;
if(y1 <= M) update_set(lc, L, M); else maintain(lc, L, M);
if(y2 > M) update_set(rc, M+, R); else maintain(rc, M+, R);
}
maintain(o, L, R);
} void query(int o, int L, int R, int add, int& _min, int& _max, int& _sum) {
if(setv[o] >= ) {
_sum += (add+setv[o]+addv[o]) * (min(R, y2)-max(L, y1)+);
_min = min(_min, setv[o]+addv[o]+add);
_max = max(_max, setv[o]+addv[o]+add);
}
else if(y1 <= L && y2 >= R) {
_sum += sumv[o] + add * (R-L+);
_min = min(_min, minv[o]+add);
_max = max(_max, maxv[o]+add);
}
else {
int M = L + (R-L)/;
if(y1 <= M) query(o*, L, M, add+addv[o], _min, _max, _sum);
if(y2 > M) query(o*+, M+, R, add+addv[o], _min, _max, _sum);
}
} void init() {
memset(setv, -, sizeof setv);
memset(addv, , sizeof addv);
memset(sumv, , sizeof sumv);
memset(minv, , sizeof minv);
memset(maxv, , sizeof maxv);
}
};
int r, c, m;
const int maxr = + ; segment_tree tree[maxr]; int main(int argc, const char * argv[]) { while(scanf("%d%d%d", &r, &c, &m) == ){ for(int i = ; i < maxr; i++) tree[i].init();
for(int i = ; i < m; i++) { scanf("%d%d%d%d%d", &q, &x1_, &y1, &x2_, &y2);
if(q == ){
scanf("%d", &v_add);
for(int x = x1_; x <= x2_; x++) {
tree[x].update_add(, , c);
}
}
if(q == ) {
scanf("%d", &v_set);
for(int x = x1_; x <= x2_; x++) {
tree[x].update_set(, , c);
}
}
if(q == ){
int gmin = INF, gmax = -INF, gsum = ;
for(int x = x1_; x <= x2_; x++) {
int _min = INF, _max = -INF, _sum = ;
tree[x].query(, , c, ,_min, _max, _sum);
gsum += _sum;
gmin = min(gmin, _min);
gmax = max(gmax, _max);
}
printf("%d %d %d\n", gsum, gmin, gmax);
}
}
}
return ;
}

UVA 11992 ——线段树(区间修改)的更多相关文章

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

    比较综合的一道题目. 二维的线段树,支持区间的add和set操作,然后询问子矩阵的sum,min,max 写完这道题也是醉醉哒,代码仓库里还有一份代码就是在query的过程中也pushdown向下传递 ...

  2. Codeforces Round #442 (Div. 2) E Danil and a Part-time Job (dfs序加上一个线段树区间修改查询)

    题意: 给出一个具有N个点的树,现在给出两种操作: 1.get x,表示询问以x作为根的子树中,1的个数. 2.pow x,表示将以x作为根的子树全部翻转(0变1,1变0). 思路:dfs序加上一个线 ...

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

  4. poj 2528 线段树区间修改+离散化

    Mayor's posters POJ 2528 传送门 线段树区间修改加离散化 #include <cstdio> #include <iostream> #include ...

  5. E - Just a Hook HDU - 1698 线段树区间修改区间和模版题

    题意  给出一段初始化全为1的区间  后面可以一段一段更改成 1 或 2 或3 问最后整段区间的和是多少 思路:标准线段树区间和模版题 #include<cstdio> #include& ...

  6. HDU 4027 Can you answer these queries? (线段树区间修改查询)

    描述 A lot of battleships of evil are arranged in a line before the battle. Our commander decides to u ...

  7. poj2528 Mayor's posters(线段树区间修改+特殊离散化)

    Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral electio ...

  8. hiho_1078_线段树区间修改

    题目 给定一组数,要求进行若干次操作,这些操作可以分为两种类型: (1) CMD 1 beg end value 将数组中下标在[beg, end] 区间内数字都变为value (2) CMD 2 b ...

  9. HDU - 1698 线段树区间修改,区间查询

    这就是很简单的基本的线段树的基本操作,区间修改,区间查询,对区间内部信息打上laze标记,然后维护即可. 我自己做的时候太傻逼了...把区间修改写错了,对给定区间进行修改的时候,mid取的是节点的左右 ...

随机推荐

  1. Ubuntu无法连接无线网

    shell里输入: su ifconfig wlan0 up 不行的话 rfkill block all rfkill unblock all ifconfig wlan0 up

  2. oracle如何回收空间?

    ALTER TABLE 名称 DEALLOCATE UNUSED [KEEP 4[M|K]] 1.当空间分配过大时,可以使用本命令 2.如果没有加KEEP,回收到水线 3.如果水线<MINEXT ...

  3. [转]GDB调试基础

    一.gdb常用命令: 命令 描述 backtrace(或bt) 查看各级函数调用及参数 finish 连续运行到当前函数返回为止,然后停下来等待命令 frame(或f) 帧编号 选择栈帧 info(或 ...

  4. Oracle基础知识点——Oracle常用权限理解:SYSDBA、SYSOPER、Normal、dba、connect、resource

    权限介绍 系统权限 含义:系统规定用户使用数据库的权限,系统权限是针对用户对数据库的操作而言(登录数据库:读取数据表.视图:删除数据库).它只是概念上的role,只是一种登录认证时的身份标识而已. S ...

  5. Java练习 SDUT-3349_答答租车系统(面向对象综合练习)

    答答租车系统(面向对象综合练习) Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 各位面向对象的小伙伴们,在学习了面向对 ...

  6. UVA_490:Rotating Sentences

    "R  Ie   n  te  h  iD  ne  kc  ,a   r  tt  he  es  r  eo  fn  oc  re  e   s  Ia   i  ad  m,  .  ...

  7. MaxCompute SQL 使用正则表达式选列

    编辑MaxCompute SQL 时,经常会需要在某个表N个列中指定一些列.若需要指定的列比较少,编写SQL时一个个输入既可.当遇到列多的时候,一个个输入就会非常费劲.本文将介绍如何在编写MaxCom ...

  8. UIView 判断是否visible

    if(self.view == [(MyAppDelegate *)[[UIApplication sharedApplication] delegate].window.subviews objec ...

  9. linux log4cplus安装和实例

    tar –xvf  log4cplus-1.1.3-rc5.tar.gz cd log4cplus-1.1.3-rc5 configure --prefix=/usr/local/log4cplus ...

  10. 几种map的排序规则

    前几天在做理事会成员的时候遇到这个问题,需要根据职务的顺序,放入对应的成员,再把成员名字按首字母拼音顺序排序后,返回给前台解析,之前一直用TreeMap来存放这个排过序的List集合,发现就算我最先循 ...