分析

这道题属于考察对于合并时不同最佳状态的讨论,我们考虑最后选出来的那三张照片位置在哪里,发现有四种情况(中间隔开处为线段树区间的 \(mid\))。

1、\(ijk\)|。

2、|\(ijk\)

3、\(ij\)|\(k\)

4、\(i\)|\(jk\)

显然前两种情况就是子节点的答案,而后两种情况需要用到以下值:最大 \(a\) 值,最大的 \(a_i-b_j(i<j)\),最大的 \(a_i-b_j(i>j)\)。而后两个值又要用到最小 \(b\) 值,所以最终我们一共维护五个值即可。

代码

#include<bits/stdc++.h>
using namespace std;
#define ls rt<<1
#define rs rt<<1|1
inline void read(int &res){
	res=0;
	int f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9')res=(res<<1)+(res<<3)+c-48,c=getchar();
	res*=f;
}
int n,m;
struct node{
	int mxa,mnb,ml,mr,as;
}a[2000005];
void pushup(node &x,node y,node z){
	x.mxa=max(y.mxa,z.mxa);
	x.mnb=min(y.mnb,z.mnb);
	x.ml=max(y.ml,max(z.ml,y.mxa-z.mnb));//最大的 a[i]-b[j](i<j)
	x.mr=max(z.mr,max(y.mr,z.mxa-y.mnb));//最大的 a[i]-b[j](i>j)
	x.as=max(y.as,max(z.as,max(y.ml+z.mxa,z.mr+y.mxa)));//答案,取四种情况最大值 
}
int csa[500005],csb[500005];
void build(int rt,int l,int r){
	if(l==r){
		a[rt].mxa=csa[l];
		a[rt].mnb=csb[l];
		a[rt].ml=a[rt].mr=a[rt].as=-1e9;//这个初值一定要赋,负答案是可能出现的 
		return;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(a[rt],a[ls],a[rs]);
}
void modifya(int rt,int l,int r,int L,int k){
	if(l==r){
		a[rt].mxa=k;
		return;
	}
	int mid=(l+r)>>1;
	if(mid>=L)modifya(ls,l,mid,L,k);
	else modifya(rs,mid+1,r,L,k);
	pushup(a[rt],a[ls],a[rs]);
}
void modifyb(int rt,int l,int r,int L,int k){
	if(l==r){
		a[rt].mnb=k;
		return;
	}
	int mid=(l+r)>>1;
	if(mid>=L)modifyb(ls,l,mid,L,k);
	else modifyb(rs,mid+1,r,L,k);
	pushup(a[rt],a[ls],a[rs]);
}
node query(int rt,int l,int r,int L,int R){
	if(l>=L&&R>=r)return a[rt];
	int mid=(l+r)>>1;
	if(mid>=R)return query(ls,l,mid,L,R);
	if(mid<L)return query(rs,mid+1,r,L,R);
	node aa=query(ls,l,mid,L,R),bb=query(rs,mid+1,r,L,R),cc;
	pushup(cc,aa,bb);
	return cc;
}
int main()
{
	read(n);read(m);
	for(int i=1;i<=n;i++){
		read(csa[i]);
	}
	for(int i=1;i<=n;i++){
		read(csb[i]);
	}
	build(1,1,n);
	while(m--){
		int op,x,y;
		read(op);read(x);read(y);
		if(op==1){
			modifya(1,1,n,x,y);
		}
		if(op==2){
			modifyb(1,1,n,x,y);
		}
		if(op==3){
			printf("%d\n",query(1,1,n,x,y).as);
		}
	}
}

posted on 2021-12-16 15:26  漠寒·  阅读(51)  评论(0编辑  收藏  举报