虽然写的有些抽象了,但是线段树查询是log n,总体应该是n log n 的,不知道时间瓶颈在哪里
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,q;
map<int,int> A;
map<int,int> B;
struct treea{
map<int,int> mn;
map<int,int> mx;
map<int,int> mnz,mnf,mxz,mxf;
map<int,int> vis;
int ls(int p){
return p*2;
}
int rs(int p){
return p*2+1;
}
void build(int p,int l,int r){
if(l==r){
mn[p]=mx[p]=A[l];
if(A[l]>0){
mxz[p]=A[l];
mnz[p]=A[l];
mnf[p]=1;
mxf[p]=-1e9;
vis[p]=0;
}else if(A[l]==0){
mxz[p]=-1;
mnz[p]=1e9;
mxf[p]=-1e9;
mnf[p]=1;
vis[p]=1;
}else if(A[l]<0){
mxf[p]=mnf[p]=A[l];
mnz[p]=1e9;
mxz[p]=-1;
vis[p]=0;
}
return;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
mn[p]=min(mn[ls(p)],mn[rs(p)]);
mx[p]=max(mx[ls(p)],mx[rs(p)]);
mnf[p]=min(mnf[ls(p)],mnf[rs(p)]);
mxf[p]=max(mxf[ls(p)],mxf[rs(p)]);
mnz[p]=min(mnz[ls(p)],mnz[rs(p)]);
mxz[p]=max(mxz[ls(p)],mxz[rs(p)]);
vis[p]=vis[ls(p)]|vis[rs(p)];
}
int querymin(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return mn[p];
}
int mid=(l+r)>>1;
int ans=1e18;
if(mid>=tl) ans=min(ans,querymin(ls(p),l,mid,tl,tr));
if(mid<tr) ans=min(ans,querymin(rs(p),mid+1,r,tl,tr));
if(ans != 1e18)return ans;
}
int querymax(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return mx[p];
}
int mid=(l+r)>>1;
int ans=-1e18;
if(mid>=tl) ans=max(ans,querymax(ls(p),l,mid,tl,tr));
if(mid<tr) ans=max(ans,querymax(rs(p),mid+1,r,tl,tr));
if(ans != -1e18)return ans;
}
int queryminz(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return mnz[p];
}
int mid=(l+r)>>1;
int ans=1e18;
if(mid>=tl) ans=min(ans,queryminz(ls(p),l,mid,tl,tr));
if(mid<tr) ans=min(ans,queryminz(rs(p),mid+1,r,tl,tr));
if(ans != 1e18)return ans;
}
int querymaxz(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return mxz[p];
}
int mid=(l+r)>>1;
int ans=-1e18;
if(mid>=tl) ans=max(ans,querymaxz(ls(p),l,mid,tl,tr));
if(mid<tr) ans=max(ans,querymaxz(rs(p),mid+1,r,tl,tr));
if(ans != -1e18)return ans;
}
int querymaxf(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return mxf[p];
}
int mid=(l+r)>>1;
int ans=-1e18;
if(mid>=tl) ans=max(ans,querymaxf(ls(p),l,mid,tl,tr));
if(mid<tr) ans=max(ans,querymaxf(rs(p),mid+1,r,tl,tr));
if(ans != -1e18)return ans;
}
int queryminf(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return mnf[p];
}
int mid=(l+r)>>1;
int ans=1e18;
if(mid>=tl) ans=min(ans,queryminf(ls(p),l,mid,tl,tr));
if(mid<tr) ans=min(ans,queryminf(rs(p),mid+1,r,tl,tr));
if(ans != 1e18)return ans;
}
int vis0(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return vis[p];
}
int mid=(l+r)>>1;
int ans=0;
if(mid>=tl) ans=max(ans,vis0(ls(p),l,mid,tl,tr));
if(mid<tr) ans=max(ans,vis0(rs(p),mid+1,r,tl,tr));
return ans;
}
};
treea a;
struct treeb{
map<int,int> mn;
map<int,int> mx;
map<int,int> mnz,mnf,mxz,mxf;
map<int,int> vis;
int ls(int p){
return p*2;
}
int rs(int p){
return p*2+1;
}
void build(int p,int l,int r){
if(l==r){
mn[p]=mx[p]=B[l];
if(B[l]>0){
mxz[p]=B[l];
mnz[p]=B[l];
mnf[p]=1;
mxf[p]=-1e9;
vis[p]=0;
}else if(B[l]==0){
mxz[p]=-1;
mnz[p]=1e9;
mxf[p]=-1e9;
mnf[p]=1;
vis[p]=1;
}else if(B[l]<0){
mxf[p]=mnf[p]=B[l];
mnz[p]=1e9;
mxz[p]=-1;
vis[p]=0;
}
return;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
mn[p]=min(mn[ls(p)],mn[rs(p)]);
mx[p]=max(mx[ls(p)],mx[rs(p)]);
mnf[p]=min(mnf[ls(p)],mnf[rs(p)]);
mxf[p]=max(mxf[ls(p)],mxf[rs(p)]);
mnz[p]=min(mnz[ls(p)],mnz[rs(p)]);
mxz[p]=max(mxz[ls(p)],mxz[rs(p)]);
vis[p]=vis[ls(p)]|vis[rs(p)];
}
int querymin(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return mn[p];
}
int mid=(l+r)>>1;
int ans=1e18;
if(mid>=tl) ans=min(ans,querymin(ls(p),l,mid,tl,tr));
if(mid<tr) ans=min(ans,querymin(rs(p),mid+1,r,tl,tr));
if(ans != 1e18)return ans;
}
int querymax(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return mx[p];
}
int mid=(l+r)>>1;
int ans=-1e18;
if(mid>=tl) ans=max(ans,querymax(ls(p),l,mid,tl,tr));
if(mid<tr) ans=max(ans,querymax(rs(p),mid+1,r,tl,tr));
if(ans != -1e18)return ans;
}
int queryminz(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return mnz[p];
}
int mid=(l+r)>>1;
int ans=1e18;
if(mid>=tl) ans=min(ans,queryminz(ls(p),l,mid,tl,tr));
if(mid<tr) ans=min(ans,queryminz(rs(p),mid+1,r,tl,tr));
if(ans != 1e18)return ans;
}
int querymaxz(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return mxz[p];
}
int mid=(l+r)>>1;
int ans=-1e18;
if(mid>=tl) ans=max(ans,querymaxz(ls(p),l,mid,tl,tr));
if(mid<tr) ans=max(ans,querymaxz(rs(p),mid+1,r,tl,tr));
if(ans != -1e18)return ans;
}
int querymaxf(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return mxf[p];
}
int mid=(l+r)>>1;
int ans=-1e18;
if(mid>=tl) ans=max(ans,querymaxf(ls(p),l,mid,tl,tr));
if(mid<tr) ans=max(ans,querymaxf(rs(p),mid+1,r,tl,tr));
if(ans != -1e18)return ans;
}
int queryminf(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return mnf[p];
}
int mid=(l+r)>>1;
int ans=1e18;
if(mid>=tl) ans=min(ans,queryminf(ls(p),l,mid,tl,tr));
if(mid<tr) ans=min(ans,queryminf(rs(p),mid+1,r,tl,tr));
if(ans != 1e18)return ans;
}
int vis0(int p,int l,int r,int tl,int tr){
if(l>=tl and r<=tr){
return vis[p];
}
int mid=(l+r)>>1;
int ans=0;
if(mid>=tl) ans=max(ans,vis0(ls(p),l,mid,tl,tr));
if(mid<tr) ans=max(ans,vis0(rs(p),mid+1,r,tl,tr));
return ans;
}
};
treeb b;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> q;
for(int i=1; i<=n; i++) cin >> A[i];
for(int i=1; i<=m; i++) cin >> B[i];
a.build(1,1,n);
b.build(1,1,m);
while(q--){
int l,r,ll,rr;
cin >> l >> r >> ll >> rr;
int mxa,mxb,mna,mnb;
bool a0,b0;
a0=b0=false;
int ax,bx;
mxa=a.querymax(1,1,n,l,r),mna=a.querymin(1,1,n,l,r);
mxb=b.querymax(1,1,m,ll,rr),mnb=b.querymin(1,1,m,ll,rr);
int ans=0;
if(mna>0){
if(mnb>0){
ans=mxa*mnb;
}else if(mxb<0){
ans=mna*mnb;
}else if(mnb<0 and mxb>0){
ans=mna*mnb;
}
}else if(mxa<0){
if(mnb>0){
ans=mxa*mxb;
}else if(mxb<0){
ans=mna*mxb;
}else if(mxb>0 and mnb<0){
ans=mxa*mxb;
}
}else if(mna<0 and mxa>0){
if(mnb>0){
ans=mxa*mnb;
}else if(mxb<0){
ans=mna*mxb;
}else if(mnb<0 and mxa>0){
ans=max(a.queryminz(1,1,n,l,r)*b.queryminf(1,1,m,ll,rr),a.querymaxf(1,1,n,l,r)*b.querymaxz(1,1,m,ll,rr));
}
}
if(a.vis0(1,1,n,l,r)) a0=1;
if(b.vis0(1,1,m,ll,rr)) b0=1;
int j=0;
if(a0) ans=max(ans,j);
if(b0) ans=min(ans,j);
cout << ans << '\n';
}
return 0;
}