码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ1513]Tet-Tetris 3D

时间:2018-02-17 21:43:35      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:线段树   覆盖   clu   get   --   gpo   统计   节点   amp   

get了新的标记永久化技能~

这题要求询问max和覆盖,因为是线段树套线段树,所以内外都不可以标记下传

这种标记永久化的套路是维护两个标记:$mx,all$,$mx$表示这个子树内的真最大值,$all$表示整个子树曾经被覆盖过这样的最大值

修改:更新经过节点的$mx$和覆盖区间节点的$all$

查询:统计经过节点的$all$和覆盖区间节点的$mx$

然后就不用下传标记了,还有写成struct会方便许多

类似地,区间加的标记永久化的两个标记是【子树和(假)】还有【子树增值】,【子树和(假)】+【子树增值】=【子树和(真)】

#include<stdio.h>
int n,m;
int max(int a,int b){return a>b?a:b;}
struct iseg{
	int mx[3010],al[3010];
	int query(int L,int R,int l,int r,int x){
		if(L<=l&&r<=R)return mx[x];
		int ans=al[x],mid=(l+r)>>1;
		if(L<=mid)ans=max(ans,query(L,R,l,mid,x<<1));
		if(mid<R)ans=max(ans,query(L,R,mid+1,r,x<<1|1));
		return ans;
	}
	void modify(int L,int R,int v,int l,int r,int x){
		mx[x]=max(mx[x],v);
		if(L<=l&&r<=R){
			al[x]=max(al[x],v);
			return;
		}
		int mid=(l+r)>>1;
		if(L<=mid)modify(L,R,v,l,mid,x<<1);
		if(mid<R)modify(L,R,v,mid+1,r,x<<1|1);
	}
};
struct oseg{
	iseg mx[3010],al[3010];
	int query(int L,int R,int Li,int Ri,int l,int r,int x){
		if(L<=l&&r<=R)return mx[x].query(Li,Ri,1,m,1);
		int ans=al[x].query(Li,Ri,1,m,1),mid=(l+r)>>1;
		if(L<=mid)ans=max(ans,query(L,R,Li,Ri,l,mid,x<<1));
		if(mid<R)ans=max(ans,query(L,R,Li,Ri,mid+1,r,x<<1|1));
		return ans;
	}
	void modify(int L,int R,int Li,int Ri,int v,int l,int r,int x){
		mx[x].modify(Li,Ri,v,1,m,1);
		if(L<=l&&r<=R)return al[x].modify(Li,Ri,v,1,m,1);
		int mid=(l+r)>>1;
		if(L<=mid)modify(L,R,Li,Ri,v,l,mid,x<<1);
		if(mid<R)modify(L,R,Li,Ri,v,mid+1,r,x<<1|1);
	}
}t;
int main(){
	int q,d,s,w,x,y;
	scanf("%d%d%d",&n,&m,&q);
	while(q--){
		scanf("%d%d%d%d%d",&d,&s,&w,&x,&y);
		t.modify(x+1,x+d,y+1,y+s,t.query(x+1,x+d,y+1,y+s,1,n,1)+w,1,n,1);
	}
	printf("%d",t.query(1,n,1,m,1,n,1));
}

[BZOJ1513]Tet-Tetris 3D

标签:线段树   覆盖   clu   get   --   gpo   统计   节点   amp   

原文地址:https://www.cnblogs.com/jefflyy/p/8452192.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!