代码很长,但多有重复部分,附加注释,请放心食用
//线段树+贪心 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;
}