标签:bzoj1513 poi2006 tet-tetris 3d 二维线段树 标记永久化
题解:题意很裸啊~~~
培训的时候说要写标记永久化,反正永久化很水,就直接写了。
但是我并不知道为什么要永久化,或者说理解不深刻,但是再遇上肯定能分析出来233。
大概应该可能或许就是:
直接原因:下传标记传不下去。
根本原因:
线段树有两层,这样它的传递可能就有点像拓扑了
就是外层线段树需要往内层线段树传,然后内层线段树还要下传
这样扫到某处时发现,****,还需要顺着两边的标记路径回溯到根,
然后各种压栈啊什么的,才能传下去,而且大概率出错(代码错或思路错)。
所以简简单单写个标记永久化好了,(反正十分简单
蒟蒻可能说错了,欢迎大神 or 新星们留言批斥。
代码(短小精悍弱爆了):
(话说你们看到我的define N不要吐槽,它的数据范围可能略弱,我是从别人那里粘来的N~~~~~)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 705 using namespace std; int n,m,q; int h,x0,x1,y0,y1; struct segment_Tree { int val[N<<2],flag[N<<2]; int query(int note=1,int L=1,int R=m,int l=y0,int r=y1) { if(L==l&&r==R)return val[note]; int mid=L+R>>1,ans=flag[note]; if(r<=mid)return max(ans,query(note<<1,L,mid,l,r)); else if(l>mid)return max(ans,query(note<<1|1,mid+1,R,l,r)); else return max(ans,max(query(note<<1,L,mid,l,mid),query(note<<1|1,mid+1,R,mid+1,r))); } void change(int note=1,int L=1,int R=m,int l=y0,int r=y1,int w=h) { val[note]=max(val[note],w); if(L==l&&r==R) { flag[note]=max(flag[note],w); return ; } int mid=L+R>>1; if(r<=mid)change(note<<1,L,mid,l,r); else if(l>mid)change(note<<1|1,mid+1,R,l,r); else change(note<<1,L,mid,l,mid),change(note<<1|1,mid+1,R,mid+1,r); } }; struct Segment_Tree { segment_Tree val[N<<2],flag[N<<2]; int query(int note=1,int L=1,int R=n,int l=x0,int r=x1) { if(L==l&&r==R)return val[note].query(); int mid=L+R>>1,ans=flag[note].query(); if(r<=mid)return max(ans,query(note<<1,L,mid,l,r)); else if(l>mid)return max(ans,query(note<<1|1,mid+1,R,l,r)); else return max(ans,max(query(note<<1,L,mid,l,mid),query(note<<1|1,mid+1,R,mid+1,r))); } void change(int note=1,int L=1,int R=n,int l=x0,int r=x1,int w=h) { val[note].change(); if(L==l&&r==R) { flag[note].change(); return ; } int mid=L+R>>1; if(r<=mid)change(note<<1,L,mid,l,r); else if(l>mid)change(note<<1|1,mid+1,R,l,r); else change(note<<1,L,mid,l,mid),change(note<<1|1,mid+1,R,mid+1,r); } }tree; int main() { // freopen("test.in","r",stdin); scanf("%d%d%d",&n,&m,&q); while(q--) { scanf("%d%d%d%d%d",&x1,&y1,&h,&x0,&y0); x1+=x0,y1+=y0,x0++,y0++; h+=tree.query(); tree.change(); } x0=y0=1,x1=n,y1=m; printf("%d\n",tree.query(1,1,n,1,n)); return 0; }
【BZOJ1513】【POI2006】Tet-Tetris 3D 二维线段树+标记永久化
标签:bzoj1513 poi2006 tet-tetris 3d 二维线段树 标记永久化
原文地址:http://blog.csdn.net/vmurder/article/details/42536835