UVa 11992 Fast Matrix Operations(两种标记的线段树)
来源:互联网 发布:c语言|是什么 编辑:程序博客网 时间:2024/05/16 17:35
本题涉及到了线段数大多数基本操作。
因为只有20行,所以可以建20个线段树。
线段树最重要的两个函数:
pushdown 下移标记,并更新子节点数据。
pushup 由2个子节点数据更新父节点数据。
写法有很多,介绍一种不容易错的:
保证在设置标记的同时更新节点信息。即:在update给某节点打标记,以及pushdown下发标记时,都马上更新节点信息。
这样写的效果是pushup很短,直接更新,因为子节点的信息已经保证被更新过了,不需要考虑标记。相反在pushdown的时候要写很长,因为要直接更新子节点。
set操作会清空add标记。
因为只有20行,所以可以建20个线段树。
线段树最重要的两个函数:
pushdown 下移标记,并更新子节点数据。
pushup 由2个子节点数据更新父节点数据。
写法有很多,介绍一种不容易错的:
保证在设置标记的同时更新节点信息。即:在update给某节点打标记,以及pushdown下发标记时,都马上更新节点信息。
这样写的效果是pushup很短,直接更新,因为子节点的信息已经保证被更新过了,不需要考虑标记。相反在pushdown的时候要写很长,因为要直接更新子节点。
set操作会清空add标记。
代码:
//// main.cpp// 11992 Fast Matrix Operations//// Created by Baoli1100 on 15/3/14.// Copyright (c) 2015年 Baoli1100. All rights reserved.//#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define maxn 800005#define INF 1000000000struct Tree{ int Sum[maxn],Min[maxn],Max[maxn],add[maxn],Set[maxn]; int sumr,minr,maxr; int op,y1,y2; void init(){ memset(Sum,0,sizeof(Sum)); memset(add,0,sizeof(add)); memset(Set,-1,sizeof(Set)); memset(Min,0,sizeof(Min)); memset(Max,0,sizeof(Max)); }; void pushup(int rt){ int lc=rt<<1,rc=rt<<1|1; Sum[rt]=Sum[lc]+Sum[rc]; Min[rt]=min(Min[lc],Min[rc]); Max[rt]=max(Max[lc],Max[rc]); } void pushdown(int rt,int L,int R){ int lc=rt<<1,rc=rt<<1|1; int M=(L+R)/2; if(Set[rt]>=0){ Set[lc]=Set[rc]=Set[rt]; add[lc]=add[rc]=0; Max[lc]=Max[rc]=Min[lc]=Min[rc]=Set[rt]; Sum[lc]=(M-L+1)*Set[rt]; Sum[rc]=(R-M)*Set[rt]; Set[rt]=-1; } if(add[rt]){ add[lc]+=add[rt]; add[rc]+=add[rt]; Max[lc]+=add[rt];Min[lc]+=add[rt]; Max[rc]+=add[rt];Min[rc]+=add[rt]; Sum[lc]+=add[rt]*(M-L+1); Sum[rc]+=add[rt]*(R-M); add[rt]=0; } } void update(int rt,int L,int R,int v){ int lc=rt<<1,rc=rt<<1|1; int M=(L+R)/2; if(y1<=L&&y2>=R){ if(op==1){ add[rt]+=v; Sum[rt]+=v*(R-L+1); Max[rt]+=v; Min[rt]+=v; } else { Set[rt]=v; add[rt]=0; Max[rt]=Min[rt]=v; Sum[rt]=v*(R-L+1); } } else{ pushdown(rt,L,R); if(y1<=M) update(lc,L,M,v); if(y2>M) update(rc,M+1,R,v); pushup(rt); } } void Query(int rt,int L,int R){ int lc=rt<<1,rc=rt<<1|1; int M=(L+R)/2; if(y1<=L&&y2>=R){ sumr+=Sum[rt]; maxr=max(maxr,Max[rt]); minr=min(minr,Min[rt]); return; } else { pushdown(rt,L,R); if(y1<=M){ Query(lc,L,M); } if(y2>M) Query(rc,M+1,R); pushup(rt); } }}T[25];int R,C,M;int main(){ while(~scanf("%d%d%d",&R,&C,&M)){ for(int i=1;i<=R;i++){ T[i].init(); } int op,x1,x2,y1,y2,v; for(int i=1;i<=M;i++){ scanf("%d",&op); if(op<3){ scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&v); for(int i=x1;i<=x2;i++){ T[i].y1=y1;T[i].y2=y2;T[i].op=op; T[i].update(1,1,C,v); } } else{ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); int rmin=INF,rmax=-INF,rsum=0; for(int i=x1;i<=x2;i++){ T[i].minr=INF;T[i].maxr=-INF;T[i].sumr=0; T[i].y1=y1;T[i].y2=y2; T[i].Query(1,1,C); rmin=min(rmin,T[i].minr); rmax=max(rmax,T[i].maxr); rsum+=T[i].sumr; } printf("%d %d %d\n",rsum,rmin,rmax); } } } return 0;}/* 3 3 111 1 1 1 1 1 1 3 1 1 1 1 2 1 1 2 2 0 3 1 1 1 1 */
0 0
- UVa 11992 Fast Matrix Operations(两种标记的线段树)
- UVA 11992 Fast Matrix Operations(线段树+延迟标记)
- uva 11992 Fast Matrix Operations(线段树)
- UVa 11992 Fast Matrix Operations 线段树
- UVA 11992 - Fast Matrix Operations(线段树)
- uva 11992 Fast Matrix Operations 线段树
- uva 11992 - Fast Matrix Operations(线段树)
- UVA - 11992 Fast Matrix Operations(线段树)
- UVA 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(线段树)
- 11992 - Fast Matrix Operations (线段树)
- UVA 11992 Fast Matrix Operations (二维线段树)
- uva 11992 Fast Matrix Operations(线段树,区间修改)
- C++编程思想简单理解
- HDU ACM 1181 变形课
- eclipse打包war
- java基础之反射
- slf4j+log4j与slf4j+logback的简单测试示例
- UVa 11992 Fast Matrix Operations(两种标记的线段树)
- Linux内核分析之(二)操作系统是如何工作的?
- 1093. Count PAT's (25)
- SpringMVC+easyUI CRUD 删除数据D
- Java HttpClient下载速率测试
- 【Unity】Mesh网格编程(二)流体
- 抽象类与接口
- Java正则表达式学习
- JVM内存大小设置