Loading

线段树套线段树

(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;
}
posted @ 2023-02-28 19:56  pjykk  阅读(67)  评论(0编辑  收藏  举报