UVA11992 Fast Matrix Operations(线段树)
来源:互联网 发布:大风刮过知乎 编辑:程序博客网 时间:2024/05/19 18:12
题目链接:点击链接
题意:
- 给一个矩阵,有三个操作。操作1,将这个矩阵的一个子矩阵的值全加上v。操作2,将这个矩阵的一个子矩阵的值全置为v。操作3,求这个矩阵的一个子矩阵的最大值,最小值,和。
思路:
看似很简单的set和add操作,我这个线段树菜鸡,卡了很久。前几天写另一道线段树时,突然明白set操作和add操作先后顺序对答案的影响。
都明白先add后set,前面的add会被置0,执行Set操作的时候,懒标记setv被置为v,懒标记addv被置为0。那么在push down的时候,会不会遇到setv和addv都不为0的情况?会的,这是先set后add的情况,此时两个标记都不为空,那么在push down操作里一定要先push down setv标记,把左儿子,右儿子的addv置0,再push down addv标记。所以push down函数里不能是if-else if的关系,而是if-if的关系。
那这样的push down函数会不会对先add后set产生影响?不会,因为每次Set的时候,都把addv置0了。即先add后set,addv为0,setv为v,先set后add,addv和setv都不为0。
代码:
#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>using namespace std;const int maxn = 1e6+100;long long _max, _min, _sum;class SegmentTree{public: int minv[maxn<<2]; int maxv[maxn<<2]; int addv[maxn<<2]; int setv[maxn<<2]; int sumv[maxn<<2]; SegmentTree(){} void build(){ memset(minv, 0, sizeof(minv)); memset(maxv, 0, sizeof(maxv)); memset(addv, 0, sizeof(addv)); memset(setv, 0, sizeof(setv)); memset(sumv, 0, sizeof(sumv)); } void pushup(int rt){ minv[rt] = min(minv[rt<<1], minv[rt<<1|1]); maxv[rt] = max(maxv[rt<<1], maxv[rt<<1|1]); sumv[rt] = sumv[rt<<1] + sumv[rt<<1|1]; } void pushdown(int rt, int len){ if(setv[rt]!=0){ addv[rt<<1] = addv[rt<<1|1] = 0; setv[rt<<1] = setv[rt<<1|1] = setv[rt]; minv[rt<<1] = minv[rt<<1|1] = setv[rt]; maxv[rt<<1] = maxv[rt<<1|1] = setv[rt]; sumv[rt<<1] = (len - len/2) * setv[rt]; sumv[rt<<1|1] = (len/2) * setv[rt]; setv[rt] = 0; } if(addv[rt]!=0){ addv[rt<<1] += addv[rt]; minv[rt<<1] += addv[rt]; maxv[rt<<1] += addv[rt]; sumv[rt<<1] += (len - len/2) * addv[rt]; addv[rt<<1|1] += addv[rt]; minv[rt<<1|1] += addv[rt]; maxv[rt<<1|1] += addv[rt]; sumv[rt<<1|1] += (len/2) * addv[rt]; addv[rt] = 0; } } void Add(int rt, int a, int b, int l, int r,int x){ if(a<=l && r<=b){ sumv[rt] += (r-l+1) * x; minv[rt] += x; maxv[rt] += x; addv[rt] += x; } else{ pushdown(rt, r-l+1); int mid = (l+r)>>1; if(a<=mid) Add(rt<<1, a, b, l, mid, x); if(mid<b) Add(rt<<1|1, a, b, mid+1, r, x); pushup(rt); } } void Set(int rt, int a, int b, int l, int r, int x){ if(a<=l && r<=b){ sumv[rt] = (r-l+1) * x; minv[rt] = x; maxv[rt] = x; addv[rt] = 0; setv[rt] = x; } else{ pushdown(rt, r-l+1); int mid = (l+r)>>1; if(a<=mid) Set(rt<<1, a, b, l, mid, x); if(mid<b) Set(rt<<1|1, a, b, mid+1, r, x); pushup(rt); } } void query(int rt, int a, int b, int l, int r){ if(a<=l && r<=b){ _sum += sumv[rt]; _min = min(_min, (long long)minv[rt]); _max = max(_max, (long long)maxv[rt]); } else{ pushdown(rt, r-l+1); int mid = (l+r)>>1; if(a<=mid) query(rt<<1, a, b, l, mid); if(mid<b) query(rt<<1|1, a, b, mid+1, r); pushup(rt); } }}matrix[22];int main(){ int r, c, m, opt, x1, y1, x2, y2, v; // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); while(scanf("%d%d%d", &r, &c, &m)!=EOF){ for(int i=1; i<=r; ++i) matrix[i].build(); for(int j=0; j<m; ++j){ scanf("%d", &opt); if(opt==1){ scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &v); for(int i=x1; i<=x2; ++i){ matrix[i].Add(1, y1, y2, 1, c, v); } } if(opt==2){ scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &v); for(int i=x1; i<=x2; ++i){ matrix[i].Set(1, y1, y2, 1, c, v); } } if(opt==3){ scanf("%d%d%d%d", &x1, &y1, &x2, &y2); _sum = 0; _min = 0x3f3f3f3f; _max = -0x3f3f3f3f; for(int i=x1; i<=x2; ++i){ matrix[i].query(1, y1, y2, 1, c); } printf("%lld %lld %lld\n", _sum, _min, _max); } } } return 0;}
阅读全文
0 0
- UVA11992 Fast Matrix Operations(线段树)
- UVA11992:Fast Matrix Operations(线段树)
- uva11992 Fast Matrix Operations (线段树)
- uva11992 - Fast Matrix Operations 区间修改 二维线段树
- UVA11992 - Fast Matrix Operations(线段树区间修改)
- [线段树双lazy]UVa11992 - Fast Matrix Operations
- uva11992 Fast Matrix Operations 线段树打标记
- Uva11992 Fast Matrix Operations(线段树区间修改+更新)
- 【UVA11992】Fast Matrix Operations——二维线段树
- UVA11992 - Fast Matrix Operations
- uva11992 Fast Matrix Operations
- 11992 - Fast Matrix Operations (线段树)
- UVA 11992 Fast Matrix Operations (线段树区间更新)
- 【UVA】11992 - Fast Matrix Operations(线段树模板)
- uva 11992 Fast Matrix Operations (线段树区间更新)
- Uva 11992 Fast Matrix Operations (二维线段树)
- 线段树(Fast Matrix Operations,UVA 11992)
- UVA 11992 Fast Matrix Operations(线段树)
- Android广告图片轮播控件,支持无限循环和5种主题,可以灵活设置轮播样式、时间、位置、图片加载框架等!
- 数据缓存
- 配置篇 07. 备份系统 ❀ Windows Server 2016
- 小丑的谢幕——OI回忆录
- 遍历map集合的四种方法
- UVA11992 Fast Matrix Operations(线段树)
- 查漏补缺,持续更新ing...
- Postgres SQL存储函数参数使用说明
- 无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动
- C语言实现括号匹配问题
- java.lang.Integer常见问题
- oracle触发器的启用和停用
- 【无用】随笔_摘抄
- 数据库操作练习2