BZOJ 1513 POI2006 Tet-Tetris 3D 二维线段树
来源:互联网 发布:dnf每隔几分钟网络中断 编辑:程序博客网 时间:2024/06/05 01:13
题目大意:给定一个矩阵,初始每个位置上的元素都是0,每次选择一个子矩形,将这个子矩形内的值修改为这个子矩形内的最大值+
我们需要维护一种数据结构,支持更新子矩形的值和查询子矩形最大值
似乎二维线段树就可以了?
但是YY了一下我们会发现两个没法解决的问题:
1.标记的下传
2.信息的上传
其实。。。
第一个很好办嘛!不下传不就好了!
标记永久化,无需下传,只要查询的时候对线段树路径上的每一个点都询问一遍就行了!
那么第二个呢?
第二个很好办嘛!不上传不就好了!
由于修改只会使元素的值增大,因此区间内只要有任意一个位置被更新过,那么就会对询问的答案产生影响
因此只需要修改的时候对线段树路径上的每一个点都修改一下就好了
于是我们维护两个标记:A标记和B标记
A标记在修改的时候精确覆盖到线段树上的每个对应节点上,查询的时候需要对所有对应节点到根的路径上的所有节点都查询
B标记恰好相反
这样就行了。。。
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 1010using namespace std;int n,m,q,ans;struct Segtree{ Segtree *ls,*rs; int val,mark; void* operator new (size_t) { static Segtree *mempool,*C; if(C==mempool) mempool=(C=new Segtree[1<<15])+(1<<15); C->ls=C->rs=0x0; C->val=C->mark=0; return C++; } void Update(int val) { this->val=max(this->val,val); mark=max(mark,val); } void Push_Up() { val=max(ls->val,rs->val); } void Push_Down() { if(!ls) ls=new Segtree; if(!rs) rs=new Segtree; if(mark) { ls->Update(mark); rs->Update(mark); mark=0; } } void Update(int x,int y,int l,int r,int val) { int mid=x+y>>1; if(x==l&&y==r) { Update(val); return ; } Push_Down(); if(r<=mid) ls->Update(x,mid,l,r,val); else if(l>mid) rs->Update(mid+1,y,l,r,val); else ls->Update(x,mid,l,mid,val) , rs->Update(mid+1,y,mid+1,r,val) ; Push_Up(); } int Query(int x,int y,int l,int r) { int mid=x+y>>1; if(x==l&&y==r) return val; Push_Down(); if(r<=mid) return ls->Query(x,mid,l,r); if(l>mid) return rs->Query(mid+1,y,l,r); return max( ls->Query(x,mid,l,mid) , rs->Query(mid+1,y,mid+1,r) ); }};struct abcd{ abcd *ls,*rs; Segtree *A,*B; void* operator new (size_t) { static abcd mempool[M<<1],*C=mempool; C->A=new Segtree; C->B=new Segtree; return C++; } void Build_Tree(int x,int y) { int mid=x+y>>1; if(x==y) return ; (ls=new abcd)->Build_Tree(x,mid); (rs=new abcd)->Build_Tree(mid+1,y); } void Update(int x,int y,int l1,int r1,int l2,int r2,int val) { int mid=x+y>>1; B->Update(1,m,l2,r2,val); if(x==l1&&y==r1) { A->Update(1,m,l2,r2,val); return ; } if(r1<=mid) ls->Update(x,mid,l1,r1,l2,r2,val); else if(l1>mid) rs->Update(mid+1,y,l1,r1,l2,r2,val); else ls->Update(x,mid,l1,mid,l2,r2,val) , rs->Update(mid+1,y,mid+1,r1,l2,r2,val) ; } int Query(int x,int y,int l1,int r1,int l2,int r2) { int mid=x+y>>1; int re=A->Query(1,m,l2,r2); if(x==l1&&y==r1) return max(re, B->Query(1,m,l2,r2) ); if(r1<=mid) return max(re, ls->Query(x,mid,l1,r1,l2,r2) ); if(l1>mid) return max(re, rs->Query(mid+1,y,l1,r1,l2,r2) ); return max(max( ls->Query(x,mid,l1,mid,l2,r2) , rs->Query(mid+1,y,mid+1,r1,l2,r2) ),re); }}*tree=new abcd;int main(){ int i,x1,y1,x2,y2,h; cin>>n>>m>>q; tree->Build_Tree(1,n); for(i=1;i<=q;i++) { scanf("%d%d%d%d%d",&x2,&y2,&h,&x1,&y1); x2+=x1;y2+=y1;x1++;y1++; int height=tree->Query(1,n,x1,x2,y1,y2); ans=max(ans,height+h); tree->Update(1,n,x1,x2,y1,y2,height+h); } cout<<ans<<endl; return 0;}
0 0
- BZOJ 1513 POI2006 Tet-Tetris 3D 二维线段树
- BZOJ 1513 [POI2006]Tet-Tetris 3D 二维线段树
- [二维线段树] BZOJ 1513 [POI2006]Tet-Tetris 3D
- BZOJ 1513: [POI2006]Tet-Tetris 3D 二维线段树
- bzoj 1513 [POI2006]Tet-Tetris 3D二维线段树
- bzoj 1513: [POI2006]Tet-Tetris 3D 二维线段树
- bzoj 1513: [POI2006]Tet-Tetris 3D(二维线段树+标记永久化)
- BZOJ1513 [POI2006]Tet-Tetris 3D 二维线段树
- 二维线段树 洛谷P3437 [POI2006]TET-Tetris 3D
- BZOJ1513: [POI2006]Tet-Tetris 3D 二维线段树
- 【BZOJ 1513】Tet-Tetris 3D【二维线段树】
- bzoj 1513: [POI2006]Tet-Tetris 3D 线段树套线段树
- 【BZOJ1513】【POI2006】Tet-Tetris 3D 二维线段树+标记永久化
- 【BZOJ】1513 [POI2006]Tet-Tetris 3D 树套树
- BZOJ 1513 POI 2006 Tet-Tetris 3D 二维线段树
- bzoj1513 Tet-Tetris 3D(二维线段树)
- 【二维线段树】poi2006 tet
- bzoj1513【POI2006】Tet-Tetris 3D
- 黑马程序员——Java基础组成
- 《统计学习方法》笔记(四)--k近邻法
- 用Pandas完成Excel中常见的任务(2)
- java Session管理
- Android开发之详解五大布局
- BZOJ 1513 POI2006 Tet-Tetris 3D 二维线段树
- Kinetis 使用eDMA完成串口接收功能
- cocoa编程第4版 8.5 挑战1 解答
- 关于UIView的autoresizingMask属性的研究
- 黑马程序员--OC基础--面向对象三大特征
- spring bean初始化和销毁
- java基础之java中的基本数据类型
- 自动布局之autoresizingMask使用详解(Storyboard&Code)
- 编程思想之多线程与多进程(3)——Java中的多线程