2019.03.24【SPOJ-GSS5】Can you answer these queries V(线段树)

版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/88784347

传送门


解析:

这是什么SB分类讨论题啊。。。

首先不会任意子区间最大子段和的请参见GSS3

那么考虑两个区间有没有相交。

如果没有,显然中间的部分是必选的。然后两边分别选择最大前缀和和最大后缀和就行了。

如果相交了,会稍微复杂一些。

相交部分是可以任意选择的。

然后对于几个前后缀分类讨论一下就行了。


代码:

#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const

namespace IO{
	inline char get_char(){
		static cs int Rlen=1<<20|1;
		static char buf[Rlen],*p1,*p2;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++; 
	}
	
	inline int getint(){
		re char c;
		re bool f=0;
		while(!isdigit(c=gc()))f^=c=='-';re int num=c^48;
		while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
		return f?-num:num;
	}
}
using namespace IO;

inline int max(int a,int b){return a<b?b:a;}

cs int N=1e4+4;
struct node{
	int lmx,rmx,sum,mx;
	node(){}
	node(cs int &_lmx,cs int &_rmx,cs int &_sum,cs int &_mx):lmx(_lmx),rmx(_rmx),sum(_sum),mx(_mx){}
	friend node operator+(cs node &l,cs node &r){
		node t;
		t.sum=l.sum+r.sum;
		t.lmx=max(l.lmx,r.lmx+l.sum);
		t.rmx=max(r.rmx,l.rmx+r.sum);
		t.mx=max(max(l.mx,r.mx),l.rmx+r.lmx);
		return t;
	}
}t[N<<2],unit=node(-0x3f3f3f3f,-0x3f3f3f3f,0,-0x3f3f3f3f);
int sum[N];

inline void build(int k,int l,int r){
	if(l==r){
		sum[l]=sum[l-1]+(t[k].sum=t[k].lmx=t[k].rmx=t[k].mx=getint());
		return ;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	t[k]=t[k<<1]+t[k<<1|1];
}

inline node query(int k,int l,int r,cs int &ql,cs int &qr){
	if(ql<=l&&r<=qr)return t[k];
	int mid=(l+r)>>1;
	if(qr<=mid)return query(k<<1,l,mid,ql,qr);
	if(mid<ql)return query(k<<1|1,mid+1,r,ql,qr);
	return query(k<<1,l,mid,ql,qr)+query(k<<1|1,mid+1,r,ql,qr);
}


int n,m,x_1,x_2,y_1,y_2;

inline node query(int l,int r){
	if(r<l)return unit;
	return query(1,1,n,l,r);
}

node t1,t2,t3;
inline void solve(){
	n=getint();
	build(1,1,n);
	m=getint();
	while(m--){
		x_1=getint(),y_1=getint(),x_2=getint(),y_2=getint();
		if(y_1<x_2){
			std::cout<<sum[x_2-1]-sum[y_1]+query(x_1,y_1).rmx+query(x_2,y_2).lmx<<"\n";
			continue;
		}
		t1=query(x_2,y_1);
		t2=query(x_1,x_2-1);
		t3=query(y_1+1,y_2);
		std::cout<<max(t1.mx,max(t2.rmx+max(t1.lmx,t1.sum+t3.lmx),t1.rmx+t3.lmx))<<"\n";
	}
}

int T;
signed main(){
	T=getint();
	std::ios::sync_with_stdio(false);
	std::cout.tie(NULL);
	while(T--)solve();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zxyoi_dreamer/article/details/88784347