萌新刚学OI,求助线段树
查看原帖
萌新刚学OI,求助线段树
42082
YZHX楼主2021/8/13 20:59

是直接分开维护最大前缀,最大后缀,最大子段,与求和的

#include<bits/stdc++.h>
using namespace std;
#define re register
#define ll long long
#define get getchar()
#define in inline
#define int ll
in int read()
{
	int t=0, x=1; char ch=get;
	while(ch!='-' && (ch<'0' || ch>'9')) ch=get;
	if(ch=='-') ch=get, x=-1;
	while(ch<='9' && ch>='0') t=t*10+ch-'0', ch=get;
	return t*x;
}
const int _=100010;
int a[_],n,m;

#define ls (k<<1)
#define rs (k<<1|1)
int pre[_<<2],suf[_<<2],sx[_<<2],sum[_<<2];
in void pushup(int k)
{
	sx[k]=suf[rs]+pre[ls], pre[k]=max(pre[ls],sum[ls]+pre[rs]);
	suf[k]=max(suf[rs],suf[ls]+sum[rs]), sum[k]=sum[rs]+sum[ls];
} 
in void build(int k,int l,int r)
{
	if(l==r){ pre[k]=suf[k]=sx[k]=sum[k]=a[l]; return ;}
	int mid=l+r>>1;
	build(ls,l,mid), build(rs,mid+1,r);
	pushup(k);
}
in int query_sum(int k,int l,int r,int x,int y)
{
	if(y<x)return 0;
	if(x<=l && r<=y){ return sum[k];}
	int mid=l+r>>1;ll s=0;
	if(x<=mid) s+=query_sum(ls,l,mid,x,y);
	if(y>mid) s+=query_sum(rs,mid+1,r,x,y);
	return s;
}
in int query_suf(int k,int l,int r,int x,int y)
{
	if(y<x) return 0;
	if(x<=l && r<=y) return suf[k];
	int mid=l+r>>1;
	if(y<=mid) return query_suf(ls,l,mid,x,y);
	if(x>mid) return query_suf(rs,mid+1,r,x,y);
	return max(query_suf(ls,l,mid,x,y)+query_sum(rs,mid+1,r,x,y), query_suf(rs,mid+1,r,x,y));
}
in int query_pre(int k,int l,int r,int x,int y)
{
	if(y<x) return 0;
	if(x<=l && r<=y) return pre[k];
	int mid=l+r>>1;
	if(y<=mid){return query_pre(ls,l,mid,x,y);}
	if(x>mid) return query_pre(rs,mid+1,r,x,y);
	return max(query_sum(ls,l,mid,x,y)+query_pre(rs,mid+1,r,x,y), query_pre(ls,l,mid,x,y));
}
in int query_sx(int k,int l,int r,int x,int y)
{
	if(y<x) return 0;
	if(x<=l && r<=y) return sx[k];
	int mid=l+r>>1;
	if(y<=mid){return query_sx(ls,l,mid,x,y);}
	if(x>mid) return query_sx(rs,mid+1,r,x,y);
	return query_suf(ls,l,mid,x,y)+query_pre(rs,mid+1,r,x,y);
}
signed main()
{
	int T=read();
	while(T--)
	{
		memset(sum,0,sizeof(sum));
		memset(suf,0,sizeof(suf));
		memset(pre,0,sizeof(pre));
		memset(sx,0,sizeof(sx));
		n=read();
		for(re int i=1;i<=n;++i) a[i]=read();
		build(1,1,n);
		m=read();
		for(re int i=1;i<=m;++i)
		{
			int l1=read(), r1=read() ,l2=read(), r2=read();
			if(r1<l2) 
				printf("%lld\n", query_suf(1,1,n,l1,r1)+query_sum(1,1,n,r1+1,l2-1)+query_pre(1,1,n,l2,r2));
			else {
				int maxx=query_suf(1,1,n,l1,l2-1)+query_pre(1,1,n,l2,r2);
				maxx=max(maxx,query_suf(1,1,n,l1,r1)+query_pre(1,1,n,r1+1,r2));
				maxx=max(maxx,query_sx(1,1,n,l2,r1));
				printf("%lld\n", maxx);
			}
		}
	}
	return 0;
}
2021/8/13 20:59
加载中...