代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int INF=1e9+10;
int read(){
int x=0,f=-1,ch=getchar();
for(;!isdigit(ch);ch=getchar()){
if(ch==-1) f=-1;
}
for(;isdigit(ch);ch=getchar())
x=x*10+ch-48;
return x;
}
struct Tree{
int z[N],mn[N*4],mx[N*4],len;
void build(int p ,int l,int r){
if(l==r){
mx[p]=mn[p]=z[l];
return;
}
int mid=(l+r)/2;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
mx[p]=max(mx[p<<1],mx[p<<1|1]);
mn[p]=min(mn[p<<1],mn[p<<1|1]);
}
int query_mx(int p,int l,int r,int L,int R){
if(L<=l&&R>=r) return mx[p];
int ans=-INF;
int mid=(l+r)/2;
if(L<=mid) ans=max(ans,query_mx(p<<1,l,mid,L,R));
if(R>mid) ans=max(ans,query_mx(p<<1|1,mid+1,r,L,R));
return ans;
}
int query_mn(int p,int l,int r,int L,int R){
if(L<=l&&R>=r) return mn[p];
int ans=INF;
int mid=(l+r)/2;
if(L<=mid) ans=min(ans,query_mn(p<<1,l,mid,L,R));
if(R>mid) ans=min(ans,query_mn(p<<1|1,mid+1,r,L,R));
return ans;
}
}A,B;
int n,m,q;
int main(){
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++) A.z[i]=read(); A.build(1,1,n);
for(int i=1;i<=m;i++) B.z[i]=read(); B.build(1,1,m);
while(q--){
int l1=read(),l2=read(),r1=read(),r2=read();
int a_mx=A.query_mx(1,1,n,l1,r1);
int b_mx=B.query_mx(1,1,m,l2,r2);
int a_mn=A.query_mn(1,1,n,l1,r1);
int b_mn=B.query_mn(1,1,m,l2,r2);
if(b_mx<0) printf("%lld\n",1ll*b_mx*a_mn);
else if(b_mn>0) printf("%lld\n",1ll*b_mn*a_mx);
else{
if(l1==r1){
if(A.z[l1]<0) printf("%lld\n",1ll*A.z[l1]*b_mx);
else printf("%lld\n",1ll*A.z[l1]*b_mn);
}else if(l2==r2){
if(B.z[l2]<0) printf("%lld\n",1ll*B.z[l2]*a_mn);
else printf("%lld\n",1ll*B.z[l2]*a_mx);
}else{
long long ans=-1ll*INF*INF;
for(int i=l1;i<=r1;i++){
long long tmp=1ll*INF*INF;
for(int j=l2;j<=r2;j++){
tmp=min(tmp,1ll*A.z[i]*B.z[j]);
}
ans=max(ans,tmp);
}
printf("%lld\n",ans);
}
}
}
//printf("%d %d\n%d %d",A.query_mx(1,1,n,1,n),A.query_mn(1,1,n,1,n),B.query_mx(1,1,n,1,m),B.query_mn(1,1,n,1,m));
return 0;
}
/*
3 2 2
0 1 -2
-3 4
1 3 1 2
2 3 2 2
5 5 10
1 2 -9 10 1
2 3 5 -10 -2
*/