解题思路:

  将矩阵每一行建立一棵线段树,进而变成一维问题求解。注意数组要开 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. POJ1485 Sumdiv

    Sumdiv Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 22680   Accepted: 5660 Descripti ...

  2. Leetcode706.Design HashMap设计哈希映射

    不使用任何内建的哈希表库设计一个哈希映射 具体地说,你的设计应该包含以下的功能 put(key, value):向哈希映射中插入(键,值)的数值对.如果键对应的值已经存在,更新这个值. get(key ...

  3. 【JZOJ4919】【NOIP2017提高组模拟12.10】神炎皇

    题目描述 神炎皇乌利亚很喜欢数对,他想找到神奇的数对. 对于一个整数对(a,b),若满足a+b<=n且a+b是ab的因子,则成为神奇的数对.请问这样的数对共有多少呢? 数据范围 对于100%的数 ...

  4. Leetcode783.Minimum Distance Between BST Nodes二叉搜索树结点最小距离

    给定一个二叉搜索树的根结点 root, 返回树中任意两节点的差的最小值. 示例: 输入: root = [4,2,6,1,3,null,null] 输出: 1 解释: 注意,root是树结点对象(Tr ...

  5. MaxCompute客户端(odpscmd)在windows命令行下查询中文乱码问题处理实践

    MaxCompute客户端工具是阿里云大数据计算服务MaxCompue产品官方客户端工具,通过客户端工具可以连接MaxCompute项目,完成包括数据管理.数据上下传.作业执行.用户及授权管理等各项操 ...

  6. 【转载】 C++ stl string 操作

        总结一下C++中string的操作,来自〈C++ Primer〉第四版. 1. string对象的定义和初始化: 12345678910111213 string s1; //空串string ...

  7. Vue.js 第2章 钩子函数&自定义指令&过滤器&计算属性&侦听器

    目标 钩子函数 自定义指令 自定义过滤器 计算属性 监听属性 局部自定义指令 为什么需要自定义指令 为了复用,为了代码的灵活 指令的分类:全局指令,局部指令 在vm外面创建的指令 通过Vue.dire ...

  8. jmeter日期处理beanshell(2)

    import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.text.P ...

  9. Android教程 -09 数据的持久化存储

    视频为本篇播客知识点讲解,建议采用超清模式观看, 欢迎点击订阅我的优酷 任何一个程序其实说白了就是在不停地和数据打交道,数据持久化就是指将那些内存中的瞬时数据保存到存储设备中,保证及时手机关机的情况下 ...

  10. PHP实现图片的等比缩放和Logo水印功能示例

    文章来自于:脚本之家 文章链接:https://www.jb51.net/article/112909.htm 这篇文章主要介绍了PHP实现图片的等比缩放和Logo水印功能,结合实例形式分析了php图 ...