线段树套线段树
(DS 记录)
problem: luoguP3437 [POI2006]TET-Tetris 3D
题意:矩形覆盖矩形最大值。(保证每个位置的值单增,这样可以用标记永久化处理)
板子。内层线段树维护列,外层线段树维护行。
因为外层线段树的结点都是线段树,所以常规的 pushup/pushdown 就寄了。我们使用标记永久化处理。
空间占用很大,不过我懒得写动态开点了。
另外一个没用的小技巧是不在线段树里存 l,r 以省空间。
反正 124.54MB/125MB 卡过去了(
(写法丑陋)
const int maxn=1001;
int d,s,n;
struct point{int maxx,cover;};
struct seg
{
point tree[maxn<<2];
void build(int x,int l,int r)
{
tree[x]=(point){0,0};
if(l==r)return;
int mid=(l+r)>>1,lson=x<<1,rson=lson|1;
build(lson,l,mid);build(rson,mid+1,r);
}
void modify(int x,int l,int r,int treel,int treer,int k)
{
if(l<=treel&&r>=treer)
{
tree[x].cover=max(tree[x].cover,k);
return;
}
tree[x].maxx=max(tree[x].maxx,k);
int mid=(treel+treer)>>1,lson=x<<1,rson=lson|1;
if(l<=mid)modify(lson,l,r,treel,mid,k);
if(r>mid)modify(rson,l,r,mid+1,treer,k);
}
int query(int x,int l,int r,int treel,int treer)
{
if(l<=treel&&r>=treer)
return max(tree[x].maxx,tree[x].cover);
int mid=(treel+treer)>>1,lson=x<<1,rson=lson|1;
int ans=tree[x].cover;
if(l<=mid)ans=max(ans,query(lson,l,r,treel,mid));
if(r>mid)ans=max(ans,query(rson,l,r,mid+1,treer));
return ans;
}
};
struct seg_point{seg maxx,cover;};
struct seg_in_seg
{
seg_point Tree[maxn<<2];
void build(int x,int l,int r)
{
Tree[x].maxx.build(1,1,s);
Tree[x].cover.build(1,1,s);
if(l==r)return;
int mid=(l+r)>>1,lson=x<<1,rson=lson|1;
build(lson,l,mid);build(rson,mid+1,r);
}
void modify(int x,int l,int r,int u,int d,int treel,int treer,int k)
{
if(l<=treel&&r>=treer)
{
Tree[x].cover.modify(1,u,d,1,s,k);
return;
}
Tree[x].maxx.modify(1,u,d,1,s,k);
int mid=(treel+treer)>>1,lson=x<<1,rson=lson|1;
if(l<=mid)modify(lson,l,r,u,d,treel,mid,k);
if(r>mid)modify(rson,l,r,u,d,mid+1,treer,k);
}
int query(int x,int l,int r,int u,int d,int treel,int treer)
{
if(l<=treel&&r>=treer)
return max(Tree[x].cover.query(1,u,d,1,s),Tree[x].maxx.query(1,u,d,1,s));
int mid=(treel+treer)>>1,lson=x<<1,rson=lson|1;
int ans=Tree[x].cover.query(1,u,d,1,s);
if(l<=mid)ans=max(ans,query(lson,l,r,u,d,treel,mid));
if(r>mid)ans=max(ans,query(rson,l,r,u,d,mid+1,treer));
return ans;
}
}segseg;
int main()
{
d=read();s=read();n=read();
segseg.build(1,1,d);
for(int i=1;i<=n;i++)
{
int len1=read(),len2=read(),h=read();
int ll=read()+1,dd=read()+1,rr=ll+len1-1,uu=dd+len2-1;
int nowh=segseg.query(1,ll,rr,dd,uu,1,d);
//printf("%d\n",nowh);
segseg.modify(1,ll,rr,dd,uu,1,d,nowh+h);
}
printf("%d\n",segseg.query(1,1,d,1,s,1,d));
return 0;
}