比较综合的一道题目。

二维的线段树,支持区间的add和set操作,然后询问子矩阵的sum,min,max

写完这道题也是醉醉哒,代码仓库里还有一份代码就是在query的过程中也pushdown向下传递标记。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 using namespace std;
  5
  6 const int maxnode = 1 << 17;
  7 int _sum, _min, _max, op, x1, x2, y1, y2, x, v;
  8
  9 struct IntervalTree
 10 {
 11     int maxv[maxnode], minv[maxnode], sumv[maxnode], setv[maxnode], addv[maxnode];
 12
 13     void maintain(int o, int L, int R)
 14     {
 15         int lc = o*2, rc = o*2+1;
 16         if(R > L)
 17         {
 18             sumv[o] = sumv[lc] + sumv[rc];
 19             minv[o] = min(minv[lc], minv[rc]);
 20             maxv[o] = max(maxv[lc], maxv[rc]);
 21         }
 22         if(setv[o] >= 0) { maxv[o] = minv[o] = setv[o]; sumv[o] = (R-L+1)*setv[o]; }
 23         if(addv[o]) { minv[o] += addv[o]; maxv[o] += addv[o]; sumv[o] += (R-L+1)*addv[o]; }
 24     }
 25
 26     void pushdown(int o)
 27     {
 28         int lc = o*2, rc = o*2+1;
 29         if(setv[o] >= 0)
 30         {
 31             setv[lc] = setv[rc] = setv[o];
 32             addv[lc] = addv[rc] = 0;
 33             setv[o] = -1;
 34         }
 35         if(addv[o])
 36         {
 37             addv[lc] += addv[o];
 38             addv[rc] += addv[o];
 39             addv[o] = 0;
 40         }
 41     }
 42
 43     void update(int o, int L, int R)
 44     {
 45         int lc = o*2, rc = o*2+1;
 46         if(y1 <= L && R <= y2)
 47         {
 48             if(op == 1) addv[o] += v;
 49             else { setv[o] = v; addv[o] = 0; }
 50         }
 51         else
 52         {
 53             pushdown(o);    //往下传递标记
 54             int M = (L + R) / 2;
 55             if(y1 <= M) update(lc, L, M); else maintain(lc, L, M);
 56             if(y2 > M) update(rc, M+1, R); else maintain(rc, M+1, R);
 57         }
 58         maintain(o, L, R);
 59     }
 60
 61     void query(int o, int L, int R, int add)
 62     {
 63         if(setv[o] >= 0)
 64         {
 65             int v = setv[o] + addv[o] + add;
 66             _sum += v * (min(y2, R) - max(y1, L) + 1);
 67             _min = min(_min, v);
 68             _max = max(_max, v);
 69         }
 70         else if(y1 <= L && R <= y2)
 71         {
 72             _sum += sumv[o] + add*(R-L+1);
 73             _min = min(_min, minv[o] + add);
 74             _max = max(_max, maxv[o] + add);
 75         }
 76         else
 77         {
 78             int M = (L + R) / 2;
 79             if(y1 <= M) query(o*2, L, M, add + addv[o]);
 80             if(y2 > M) query(o*2+1, M+1, R, add + addv[o]);
 81         }
 82     }
 83 };
 84
 85 const int maxr = 20 + 5;
 86 const int INF = 1000000000;
 87
 88 IntervalTree tree[maxr];
 89
 90 int main()
 91 {
 92     //freopen("in.txt", "r", stdin);
 93
 94     int r, c, m;
 95     while(scanf("%d%d%d", &r, &c, &m) == 3)
 96     {
 97         memset(tree, 0, sizeof(tree));
 98         for(int x = 1; x <= r; x++)
 99         {
100             memset(tree[x].setv, -1, sizeof(tree[x].setv));
101             tree[x].setv[1] = 0;
102         }
103
104         while(m--)
105         {
106             scanf("%d%d%d%d%d", &op, &x1, &y1, &x2, &y2);
107             if(op < 3)
108             {
109                 scanf("%d", &v);
110                 for(x = x1; x <= x2; x++) tree[x].update(1, 1, c);
111             }
112             else
113             {
114                 _sum = 0; _max = -INF; _min = INF;
115                 for(x = x1; x <= x2; x++) tree[x].query(1, 1, c, 0);
116                 printf("%d %d %d\n", _sum, _min, _max);
117             }
118         }
119     }
120
121     return 0;
122 }

代码君

转载于:https://www.cnblogs.com/AOQNRMGYXLMV/p/4384161.html

UVa 11992 (线段树 区间修改) Fast Matrix Operations相关推荐

  1. 【模板】线段树区间修改

    区间修改: 区间修改过程类似于区间询问,例如将[ul, ur]内的所有元素都加上v,则进行如下操作: 当当前区间被区间[ul, ur]所包含时, 当前的节点值加上区间长度(r - l  + 1)乘以v ...

  2. python:线段树区间修改 + 区间查询 模板 + 坑点总结

    from functools import reduceclass SegTree:'''支持增量更新,覆盖更新,序列更新,任意RMQ操作基于二叉树实现初始化:O(1)增量更新或覆盖更新的单次操作复杂 ...

  3. UVA - 11992 线段树

    UVA - 11992 题意:有一个 r*c 的全 0矩阵, 进行 3 种操作. 1 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中 ...

  4. POJ 2777 Count Color (线段树区间修改 + 状态压缩)

    题目链接:POJ 2777 Count Color [题目大意] 给你 n 块板子, 编号1--n , 板子的颜色最多30种, 初始时  板子的颜色都是 1: 有两种操作 1 .把给定区间的板子染成一 ...

  5. HDU 1698 Just a Hook (线段树区间修改+区间查询)

    题目链接: 传送门 题意:Pudge对装备钩子进行若干次的强化,强化分为三种分别对应的价值是1,2,3,在经历过若干次操作后,输出钩子对应的总价值,每次强化都是对钩子进行区间修改 解题思路:在明白了题 ...

  6. hdu1698(线段树/区间修改/求和)

    hdu1698"Just a Hook" 题意: 有一个区间s [1,n],每一节si的初始价值为1.定义操作:x y val,将区间[x,y]中的每一个小节的价值改为val.问: ...

  7. 1631 小鲨鱼在51nod小学(线段树区间修改+单点查询:不用下传lazy的区间修改)

    题目描述: 1631 小鲨鱼在51nod小学 鲨鱼巨巨2.0(以下简称小鲨鱼)以优异的成绩考入了51nod小学.并依靠算法方面的特长,在班里担任了许多职务. 每一个职务都有一个起始时间A和结束时间B, ...

  8. codeforces:E2. Array and Segments (Hard version)【线段树 + 区间修改】

    分析 思路很简单 遍历每个作为最大值,然后区间不包含当前最大值的都可以减掉 easy version就可以这样暴力解决 然后求出最大差值 暴力解法 import sys input = sys.std ...

  9. 【UOJ 53】线段树区间修改

    [题目描述]: 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 [输入描述]: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...

最新文章

  1. 数据、算法岗的几点经验分享!
  2. 为什么我的cpld需要重新上电才能工作_正压型防爆配电箱的调试工作
  3. IIS中保持HTTP连接
  4. 【软件开发底层知识修炼】八 Binutils辅助工具之- objdump工具 与 size,strings工具
  5. Python 开发工具集:关于文档、测试、调试、程序的优化和分析
  6. 微信小程序实现语音识别功能
  7. 根据Java源码生成流程图
  8. SDRAM 控制器(八)——FIFO控制模块
  9. 自己动手,解决微信投票提示“投票失败”问题
  10. 大数据战略能不能打造第二个百度?
  11. Windows和Linux双系统时间误差8小时解决方案
  12. Power BI_柱状图中间空一列_横坐标显示
  13. gamemaker学习笔记:打包Android过程记录
  14. android 默认启动器,安卓启动器_安卓默认启动器如何替换?
  15. 【泡泡机器人公开课】公开课链接 机器人俱乐部
  16. 管理后台服务通用化设计拙见
  17. 一个假冒的序列号被用来注册Internet Download Manager。IDM即将退出…
  18. python基础数据类型练习2
  19. 第十章 集成ISIS协议--10.1
  20. 程序员必修之路---离职与劳动仲裁的纠纷解决

热门文章

  1. 一步一步学WF系列(四)——工作流模拟登陆
  2. strcmp可以比较数组么_数组:总结篇
  3. opengl 创建context_OpenGL专业名词解析
  4. 360浏览器清除缓存_微信缓存清理教程
  5. 网页HTML5制作flex布局骰子,CSS3的Flexbox骰子布局的实现及分析
  6. c语言非法字符空格,98行的四则计算器.(支持括号)加入了非法字符的检测
  7. python 艺术照片滤镜_Python实现PS滤镜Fish lens图像扭曲效果示例
  8. keil复制代码乱码_成都控制器开发:容易忽略!用KEIL编码汉字也会有BUG
  9. php前后分离的工作写法,[前后端分离项目]thinkphp返回给前端数据为字符串
  10. 算法提高 高精度乘法(java)