#线段树,分治,扫描线#洛谷 6109 [Ynoi2009] rprmq1

题目传送门


分析

首先将询问离线,在x轴上扫描线相当于视作时间轴,

那么矩形加实际上就是线段树上区间加,矩形最大值相当于查询一段时间内的区间最大值。

不妨将时间区间也就是x轴分治,没有跨过中点的递归处理,

跨过中点的一定可以被分成从 \(mid\) 往前的一段和从 \(mid+1\) 往后的一段。

此时我们还需要在线段树上维护历史最大值,问题是这个历史只能从 \(mid\) 或者 \(mid+1\) 开始算起。

因此还需要维护一个懒标记用来将当前历史最大值赋为当前最大值,在设置该懒标记时先要将区间加的懒标记下放。

除此之外,下放的顺序是先下放 \(hmx[k]=mx[k]\) 的懒标记再下放区间加的懒标记。


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <vector>
using namespace std;
const int N=50011; typedef long long lll;
struct rec{int l1,r1,l2,r2,rk;}q[N*10],_q[N*10];
struct Rec{
	int l,r,z;
	bool operator <(const Rec &t)const{
		return z<t.z;
	}
};
vector<Rec>K[N]; lll ans[N*10]; int n,m,Q;
int iut(){
	int ans=0,f=1; char c=getchar();
	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
	return ans*f;
}
void print(lll ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
bool cmp1(rec x,rec y){
	return x.r1<y.r1;
}
bool cmp2(rec x,rec y){
	return x.l1>y.l1;
}
struct Segment_Tree{
	lll mx[N<<2][2],lazy[N<<2][2],tag[N<<2];
	void pup(int k){
		mx[k][0]=max(mx[k<<1][0],mx[k<<1|1][0]);
		mx[k][1]=max(mx[k<<1][1],mx[k<<1|1][1]);
	}
	void ptag(int k,lll z,lll Z){
		mx[k][1]=max(mx[k][1],mx[k][0]+Z);
		lazy[k][1]=max(lazy[k][1],lazy[k][0]+Z);
		mx[k][0]+=z,lazy[k][0]+=z;
	}
	void Reset(int k,int l,int r){
		if (lazy[k][0]){
			if (l!=r){
				ptag(k<<1,lazy[k][0],lazy[k][1]);
				ptag(k<<1|1,lazy[k][0],lazy[k][1]);
			}
			lazy[k][0]=0;
		}
		lazy[k][1]=0,mx[k][1]=mx[k][0],tag[k]=1;
	}
	void pdown(int k,int l,int mid,int r){
		if (tag[k]){
			Reset(k<<1,l,mid);
			Reset(k<<1|1,mid+1,r);
			tag[k]=0;
		}
		if (lazy[k][0]||lazy[k][1]){
			ptag(k<<1,lazy[k][0],lazy[k][1]);
			ptag(k<<1|1,lazy[k][0],lazy[k][1]);
			lazy[k][0]=lazy[k][1]=0;
		}
	}
	void update(int k,int l,int r,int x,int y,lll z){
		if (l==x&&r==y){
			ptag(k,z,z);
			return;
		}
		int mid=(l+r)>>1;
		pdown(k,l,mid,r);
		if (y<=mid) update(k<<1,l,mid,x,y,z);
		else if (x>mid) update(k<<1|1,mid+1,r,x,y,z);
			else update(k<<1,l,mid,x,mid,z),update(k<<1|1,mid+1,r,mid+1,y,z);
		pup(k);
	}
	lll query(int k,int l,int r,int x,int y){
		if (l==x&&r==y) return mx[k][1];
		int mid=(l+r)>>1;
		pdown(k,l,mid,r);
		if (y<=mid) return query(k<<1,l,mid,x,y);
		else if (x>mid) return query(k<<1|1,mid+1,r,x,y);
			else return max(query(k<<1,l,mid,x,mid),query(k<<1|1,mid+1,r,mid+1,y));
	}
}Tre;
void Add(int x){
	for (int i=0;i<(int)K[x].size();++i)
		Tre.update(1,1,n,K[x][i].l,K[x][i].r,K[x][i].z);
}
void Del(int x){
	for (int i=K[x].size()-1;~i;--i)
		Tre.update(1,1,n,K[x][i].l,K[x][i].r,-K[x][i].z);
}
void Max(lll &x,lll y){x=x>y?x:y;}
void dfs(int L,int R,int l,int r){
	if (l>r) return;
	if (L==R){
		Add(L);
		Tre.Reset(1,1,n);
		for (int i=l;i<=r;++i)
			ans[q[i].rk]=max(ans[q[i].rk],Tre.query(1,1,n,q[i].l2,q[i].r2));
		Del(L);
		return;
	}
	int mid=(L+R)>>1,_l=l,_r=r;
	for (int i=l;i<=r;++i)
		if (q[i].r1<=mid) _q[_l++]=q[i];
	for (int i=r;i>=l;--i)
		if (q[i].l1>mid) _q[_r--]=q[i];
	for (int i=l;i<=r;++i)
		if (q[i].r1<=mid) _q[_l++]=q[i];
			else if (q[i].>mid) _q[__l++]=q[i];
	for (int i=l;i<=r;++i) q[i]=_q[i];
	dfs(L,mid,l,_l-1);
	for (int i=L;i<=mid;++i) Add(i);
	if (_l<=_r){
		for (int i=mid+1,j=_l;i<=R;++i){
			Add(i);
			if (i==mid+1) Tre.Reset(1,1,n);
			for (;j<=_r&&q[j].r1==i;++j)
				Max(ans[q[j].rk],Tre.query(1,1,n,q[j].l2,q[j].r2));
		}
		for (int i=R;i>mid;--i) Del(i);
	}
	dfs(mid+1,R,_r+1,r);
	sort(q+_l,q+1+_r,cmp2);
	Tre.Reset(1,1,n);
	for (int i=mid,j=_l;i>=L;Del(i--))
	for (;j<=_r&&q[j].l1==i;++j)
		Max(ans[q[j].rk],Tre.query(1,1,n,q[j].l2,q[j].r2));
}
int main(){
	n=iut(),m=iut(),Q=iut();
	for (int i=1;i<=m;++i){
		int l1=iut(),l2=iut(),r1=iut(),r2=iut(),z=iut();
		K[l1].push_back((Rec){l2,r2,z});
		if (r1<n) K[r1+1].push_back((Rec){l2,r2,-z});
	}
	for (int i=1;i<=n;++i) sort(K[i].begin(),K[i].end());
	for (int i=1;i<=Q;++i){
		int l1=iut(),l2=iut(),r1=iut(),r2=iut();
		q[i]=(rec){l1,r1,l2,r2,i};
	}
	sort(q+1,q+1+Q,cmp1);
	dfs(1,n,1,Q);
	for (int i=1;i<=Q;++i) print(ans[i]),putchar(10);
	return 0;
}
posted @ 2026-10-14 11:08  lemondinosaur  阅读(7)  评论(0)    收藏  举报