线段树+贪心(带注释)40pts
查看原帖
线段树+贪心(带注释)40pts
680022
Rice_Demon_King楼主2024/7/24 15:41

题目传送门

代码很长,但多有重复部分,附加注释,请放心食用

//线段树+贪心 40pts 
#include<bits/stdc++.h>
#define MAXN 100009
#define For(i,j,k) for(int i=j;i<=k;++i)
#define dFor(i,j,k) for(int i=j;i>=k;--i)
#define ll long long
const ll INF=1e9; //INF/-INF相当于空集 
using namespace std;
int n,m,q;
ll a[MAXN],b[MAXN];
struct MAXtree{		//线段树 
	int l,r;
	bool zero;	//[l,r]内有0则为true,反之则为0 
	ll posi_maxn,nega_maxn,posi_minn,nega_minn;	//posi-:正数  nega-:负数  maxn:最大值 minn:最小值 
}Atree[4*MAXN],Btree[4*MAXN];
void Atree_build(int now,int L,int R){		//维护A数组的区间最值 
	Atree[now].l=L,Atree[now].r=R;
	if(L==R){
		if(a[L]>0){
			Atree[now].posi_maxn=a[L];
			Atree[now].nega_maxn=-INF;
			Atree[now].posi_minn=a[L];
			Atree[now].nega_minn=INF;
			Atree[now].zero=false;
		} 
		else if(a[L]==0){
			Atree[now].posi_maxn=-INF;
			Atree[now].nega_maxn=-INF;
			Atree[now].posi_minn=INF;
			Atree[now].nega_minn=INF;
			Atree[now].zero=true;
		}
		else{
			Atree[now].posi_maxn=-INF;
			Atree[now].nega_maxn=a[L];
			Atree[now].posi_minn=INF;
			Atree[now].nega_minn=a[L];
			Atree[now].zero=false;
		}
		//cout<<Atree[now].l<<' '<<Atree[now].r<<' '<<Atree[now].zero<<" "<<Atree[now].posi_maxn<<" "<<Atree[now].posi_minn<<" "<<Atree[now].nega_maxn<<' '<<Atree[now].nega_minn<<endl;
		return ;
	}
	int mid=(L+R)/2;
	Atree_build(now*2,L,mid);
	Atree_build(now*2+1,mid+1,R);
	Atree[now].posi_maxn=max(Atree[now*2].posi_maxn,Atree[now*2+1].posi_maxn);
	Atree[now].nega_maxn=max(Atree[now*2].nega_maxn,Atree[now*2+1].nega_maxn); 
	Atree[now].posi_minn=min(Atree[now*2].posi_minn,Atree[now*2+1].posi_minn); 
	Atree[now].nega_minn=min(Atree[now*2].nega_minn,Atree[now*2+1].nega_minn); 
	Atree[now].zero=(Atree[now*2].zero==true||Atree[now*2+1].zero==true?true:false);
	//cout<<Atree[now].l<<' '<<Atree[now].r<<' '<<Atree[now].zero<<" "<<Atree[now].posi_maxn<<" "<<Atree[now].posi_minn<<" "<<Atree[now].nega_maxn<<' '<<Atree[now].nega_minn<<endl;
}
void Btree_build(int now,int L,int R){ 		//维护B数组的区间最值 
	Btree[now].l=L,Btree[now].r=R;
	if(L==R){
		if(b[L]>0){
			Btree[now].posi_maxn=b[L];
			Btree[now].nega_maxn=-INF;
			Btree[now].posi_minn=b[L];
			Btree[now].nega_minn=INF;
			Btree[now].zero=false;
		} 
		else if(b[L]==0){
			Btree[now].posi_maxn=-INF;
			Btree[now].nega_maxn=-INF;
			Btree[now].posi_minn=INF;
			Btree[now].nega_minn=INF;
			Btree[now].zero=true;
		}
		else{
			Btree[now].posi_maxn=-INF;
			Btree[now].nega_maxn=b[L];
			Btree[now].posi_minn=INF;
			Btree[now].nega_minn=b[L];
			Btree[now].zero=false;
		}
		//cout<<Btree[now].l<<" "<<Btree[now].r<<' '<<Btree[now].zero<<" "<<Btree[now].posi_maxn<<" "<<Btree[now].posi_minn<<" "<<Btree[now].nega_maxn<<' '<<Btree[now].nega_minn<<endl;
		return ;
	}
	int mid=(L+R)/2;
	Btree_build(now*2,L,mid);
	Btree_build(now*2+1,mid+1,R);
	Btree[now].posi_maxn=max(Btree[now*2].posi_maxn,Btree[now*2+1].posi_maxn);
	Btree[now].nega_maxn=max(Btree[now*2].nega_maxn,Btree[now*2+1].nega_maxn); 
	Btree[now].posi_minn=min(Btree[now*2].posi_minn,Btree[now*2+1].posi_minn); 
	Btree[now].nega_minn=min(Btree[now*2].nega_minn,Btree[now*2+1].nega_minn);
	Btree[now].zero=(Btree[now*2].zero==true||Btree[now*2+1].zero==true?true:false);
	//cout<<Btree[now].l<<" "<<Btree[now].r<<' '<<Btree[now].zero<<" "<<Btree[now].posi_maxn<<" "<<Btree[now].posi_minn<<" "<<Btree[now].nega_maxn<<' '<<Btree[now].nega_minn<<endl;
}
ll AQuery(int now,int L,int R,int op){ //查询A数组的区间[L,R]内op对应的值 
	int tl=Atree[now].l,tr=Atree[now].r;
	if(tl==L&&tr==R){
		if(op==1) return Atree[now].posi_maxn;
		if(op==2) return Atree[now].nega_maxn;
		if(op==3) return Atree[now].posi_minn;
		if(op==4) return Atree[now].nega_minn;
		if(op==5) return (Atree[now].zero==true?1ll:0ll);
	}
	int mid=(tl+tr)/2;
	if(R<=mid) return AQuery(now*2,L,R,op);
	if(L>=mid+1) return AQuery(now*2+1,L,R,op);
	if(op==5) return (AQuery(now*2,L,mid,op)==1ll||AQuery(now*2+1,mid+1,R,op)==1ll?1ll:0ll);
	if(op==1||op==2) return max(AQuery(now*2,L,mid,op),AQuery(now*2+1,mid+1,R,op));
	return min(AQuery(now*2,L,mid,op),AQuery(now*2+1,mid+1,R,op));
}
ll BQuery(int now,int L,int R,int op){ 	////查询B数组的区间[L,R]内op对应的值  
	int tl=Btree[now].l,tr=Btree[now].r;
	if(tl==L&&tr==R){
		if(op==1) return Btree[now].posi_maxn;
		if(op==2) return Btree[now].nega_maxn;
		if(op==3) return Btree[now].posi_minn;
		if(op==4) return Btree[now].nega_minn;
		if(op==5) return (Btree[now].zero==true?1ll:0ll);
	}
	int mid=(tl+tr)/2;
	if(R<=mid) return BQuery(now*2,L,R,op);
	if(L>=mid+1) return BQuery(now*2+1,L,R,op);
	if(op==5) return (BQuery(now*2,L,mid,op)==1ll||BQuery(now*2+1,mid+1,R,op)==1ll?1ll:0ll);
	if(op==1||op==2) return max(BQuery(now*2,L,mid,op),BQuery(now*2+1,mid+1,R,op));
	return min(BQuery(now*2,L,mid,op),BQuery(now*2+1,mid+1,R,op));
}
int main(){
	ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m>>q;
    For(i,1,n) cin>>a[i];
    For(i,1,m) cin>>b[i];
    //cout<<endl;
    Atree_build(1,1,n);
    //cout<<endl;
	Btree_build(1,1,m);
    //cout<<endl;
    while(q--){
    	int l1,r1,l2,r2;
    	bool A_zero=false,A_posi=false,A_nega=false,B_zero=false,B_posi=false,B_nega=false; 
		ll Aposi_maxn,Anega_maxn,Aposi_minn,Anega_minn,Azero;
		ll Bposi_maxn,Bnega_maxn,Bposi_minn,Bnega_minn,Bzero;
    	cin>>l1>>r1>>l2>>r2;
    	//Query(int now,int L,int R,int op)
    	//op=1:查posi_maxn   op=2:查nega_maxn  op=3:查posi_minn  op=4:查nega_minn  op=5:查zero 
    	Aposi_maxn=AQuery(1,l1,r1,1),Anega_maxn=AQuery(1,l1,r1,2);
		Aposi_minn=AQuery(1,l1,r1,3),Anega_minn=AQuery(1,l1,r1,4);
		Bposi_maxn=BQuery(1,l2,r2,1),Bnega_maxn=BQuery(1,l2,r2,2);
		Bposi_minn=BQuery(1,l2,r2,3),Bnega_minn=BQuery(1,l2,r2,4);
		Azero=AQuery(1,l1,r1,5),Bzero=BQuery(1,l2,r2,5);
		A_zero=(Azero==1ll?true:false);
		A_posi=(abs(Aposi_maxn)==INF?false:true);
		A_nega=(abs(Anega_maxn)==INF?false:true);
		B_zero=(Bzero==1ll?true:false);
		B_posi=(abs(Bposi_maxn)==INF?false:true);
		B_nega=(abs(Bnega_maxn)==INF?false:true);
//		cout<<endl;
//		cout<<"A:   "<<A_zero<<" "<<Aposi_maxn<<" "<<Aposi_minn<<" "<<Anega_maxn<<" "<<Anega_minn<<endl;
//		cout<<"B:   "<<B_zero<<" "<<Bposi_maxn<<" "<<Bposi_minn<<" "<<Bnega_maxn<<" "<<Bnega_minn<<endl;
//		cout<<endl;
    	ll ans=-INF;  //贪心 
    	if(A_posi==true){
    		if(B_nega==true) ans=max(ans,Aposi_minn*Bnega_minn);
    		else if(B_zero==true) ans=max(ans,0ll);
    		else ans=max(ans,Aposi_maxn*Bposi_minn);
		}
		if(A_zero==true) ans=max(ans,0ll);
		if(A_nega==true){
			if(B_posi==true) ans=max(ans,Anega_maxn*Bposi_maxn);
			else if(B_zero==true) ans=max(ans,0ll);
			else ans=max(ans,Anega_minn*Bnega_maxn);
		}
	cout<<ans<<endl;
	}
	return 0;
}
2024/7/24 15:41
加载中...