UVa 11992 add与set结合区间修改线段树
来源:互联网 发布:寄生虫推广软件 编辑:程序博客网 时间:2024/05/16 12:23
差点忘记还有这么一个线段树的题目,白书上的最后一个例题了,也是足见其难度啊,和一般的题目就是不一样,这个需要考虑的是set和add两种情况同时存在的情况了,这个需要考虑的就是当add先在某一段区间标记了,那么如果下一次当该区间又标记了set的话,实际上前面做到add就没用了,可以直接被抹去了,而如果在set之后又来了一次的set的话,那样的话两者都需要保留下来,那么难点就来了,在pushdown这里的话,肯定需要先判读set标记了,如果set存在的话那么对其左右子树进行各种操作了,特别的需要对左右子节点的add标志要清零,因为下面对左右子节点的set要进行操作了那就和前面说道的一样,set出现,那么之前的add都不算数了,其他的各种指标只要合理操作即可了。
这题还是有点难度的,参考了这篇博文:http://blog.csdn.net/a601025382s/article/details/38356535
还有就是我的这里的代码的写法不如上面博客的,因为写惯了不是结构体的写法,在这个多指标的情况下,其实还是一开始就直接写结构体会来的更加方便一些。
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1#define mid int m = (l + r)>>1const int maxn=10e6+5;int r,c,m,tag,x1,x2,y1,y2,v;int adds[maxn<<2],sets[maxn<<2],sum[maxn<<2],maxs[maxn<<2],mins[maxn<<2];struct node{ int sum,maxs,mins;};void build(int l,int r,int rt){ adds[rt]=sets[rt]=sum[rt]=maxs[rt]=mins[rt]=0; if(l==r) return ; mid; build(lson); build(rson);}void pushdown(int l,int r,int rt){ if(sets[rt]!=0)//当有两个标记时,必定是add要在set之后做的 { adds[rt*2]=adds[rt*2+1]=0; sets[rt*2]=sets[rt*2+1]=sets[rt]; mins[rt*2]=mins[rt*2+1]=maxs[rt*2]=maxs[rt*2+1]=sets[rt]; mid; sum[rt*2]=(m-l+1)*sets[rt]; sum[rt*2+1]=(r-m)*sets[rt]; sets[rt]=0; } if(adds[rt]!=0) { adds[rt*2]+=adds[rt]; adds[rt*2+1]+=adds[rt]; maxs[rt*2]+=adds[rt]; maxs[rt*2+1]+=adds[rt]; mins[rt*2]+=adds[rt]; mins[rt*2+1]+=adds[rt]; mid; sum[rt*2]+=(m-l+1)*adds[rt]; sum[rt*2+1]+=(r-m)*adds[rt]; adds[rt]=0; }}void update_add(int l,int r,int rt,int x,int y,int z){ if(x<=l&&y>=r) { adds[rt]+=z; maxs[rt]+=z; mins[rt]+=z; sum[rt]+=(r-l+1)*z; return ; } mid; pushdown(l,r,rt); if(x<=m) update_add(lson,x,y,z); if(y>m) update_add(rson,x,y,z); maxs[rt]=max(maxs[rt*2],maxs[rt*2+1]); mins[rt]=min(mins[rt*2],mins[rt*2+1]); sum[rt]=sum[rt*2]+sum[rt*2+1];}void update_set(int l,int r,int rt,int x,int y,int z){ if(x<=l&&y>=r) { adds[rt]=0;//因为置位set的优先级肯定要高啊,因为不管先前add了多少的值在这段区间,如果只要出现了一次的set那么值都是set放的z值 sets[rt]=z; maxs[rt]=z; mins[rt]=z; sum[rt]=(r-l+1)*z; return ; } pushdown(l,r,rt); mid; if(x<=m) update_set(lson,x,y,z); if(y>m) update_set(rson,x,y,z); maxs[rt]=max(maxs[rt*2],maxs[rt*2+1]); mins[rt]=min(mins[rt*2],mins[rt*2+1]); sum[rt]=sum[rt*2]+sum[rt*2+1];}node query(int l,int r,int rt,int x,int y){ if(x<=l&&y>=r) { node tmp; tmp.maxs=maxs[rt]; tmp.mins=mins[rt]; tmp.sum=sum[rt]; return tmp; } pushdown(l,r,rt); mid; node t; if(y<=m) return query(lson,x,y); else if(x>m) return query(rson,x,y); else { node p,q; p=query(lson,x,y); q=query(rson,x,y); t.sum=p.sum+q.sum; t.maxs=max(p.maxs,q.maxs); t.mins=min(p.mins,q.mins); return t; }}int main(){ while(scanf("%d%d%d",&r,&c,&m)!=EOF) { build(1,r*c,1); while(m--) { scanf("%d%d%d%d%d",&tag,&x1,&y1,&x2,&y2); if(tag==3) { node ans,p; for(int i=x1;i<=x2;i++) { if(i==x1) ans=query(1,r*c,1,(i-1)*c+y1,(i-1)*c+y2); else { p=query(1,r*c,1,(i-1)*c+y1,(i-1)*c+y2); ans.sum+=p.sum; ans.maxs=max(ans.maxs,p.maxs); ans.mins=min(ans.mins,p.mins); } } printf("%d %d %d\n",ans.sum,ans.mins,ans.maxs); } else if(tag==2) { scanf("%d",&v); for(int i=x1;i<=x2;i++) update_set(1,r*c,1,(i-1)*c+y1,(i-1)*c+y2,v); } else if(tag==1) { scanf("%d",&v); for(int i=x1;i<=x2;i++) update_add(1,r*c,1,(i-1)*c+y1,(i-1)*c+y2,v); } } } return 0;}
0 0
- UVa 11992 add与set结合区间修改线段树
- 线段树--区间修改set,区间更新add
- 二维线段树区间修改(add,set)uva11992
- Uva 11992 - Fast Matrix Operations题解(线段树区间更新+区间Set+Add,查询最大值,最小值,总和)
- zoj3911 线段树区间修改与求素数的结合
- 线段树(2):区间修改 (uva 11992 FastMatrixOperations)
- uva 11992 Fast Matrix Operations(线段树,区间修改)
- UVA - 11992 Fast Matrix Operations 线段树(区间修改)
- hihocoder 1080 更为复杂的买卖房屋姿势(线段树经典操作,区间修改,add+set标记)
- POJ 2528 & UVA 10587(线段树+离散+区间修改)
- Fast Matrix Operations uva+线段树区间修改
- SKYLINE uva+线段树+区间的修改+lazy标记
- UVa 1232 SKYLINE (线段树区间修改)
- 线段树区间修改
- 线段树区间修改
- 线段树区间修改
- UVa 11992 Fast Matrix Operations (线段树区间修改大杂烩)
- POJ 3468<线段树,区间add>
- Cocoapods1.0.1版本安装教程
- 浏览器http的缓存机制
- c++DLL封装DLL问题
- Linux学习总结(1)
- 邓白氏码的申请
- UVa 11992 add与set结合区间修改线段树
- iOS crash 崩溃问题的追踪方法
- SVN Problem
- SLam学习网站整理
- 构造器与方法区别
- 安卓中对库等依赖的详解
- TestNG测试报告美化
- matplot绘制bar图--python绘图
- JNA -->JNI的终结者(一)