纯用线段树敲的,马蜂丑陋,还请海涵。
本人建了两个线段树,分别存a数组和b数组正数最大最小值和负数最大最小值,然后分别去求区间内所需的最值。
code:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<sstream>
#include<set>
#define ls p>>1
#define rs (p>>1)+1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+10,M=1e5+10;
const double PI=acos(-1.0);
const double eps=1e-6;
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;
inline int read(){
int f=1,x=0; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
return f*x;
}
int n,m,q;
int a[N],b[N];
struct node{
int max_zhenga=-INF,max_zhengb=-INF;
int min_zhenga=INF,min_zhengb=INF;
int max_fua=-INF,max_fub=-INF;
int min_fua=INF,min_fub=INF;
}t1[2*N],t2[2*N];
void build_a(int l,int r,int p){
if(l==r){
if(a[l]>=0){
t1[p].max_zhenga=a[l];
t1[p].min_zhenga=a[l];
}
else{
t1[p].max_fua=a[l];
t1[p].min_fua=a[l];
}
return;
}
int mid=(l+r)>>1;
build_a(l,mid,ls);
build_a(mid+1,r,rs);
t1[p].max_zhenga=max(t1[ls].max_zhenga,t1[rs].max_zhenga);
t1[p].min_zhenga=min(t1[ls].min_zhenga,t1[rs].min_zhenga);
t1[p].max_fua=max(t1[ls].max_fua,t1[rs].max_fua);
t1[p].min_fua=min(t1[ls].min_fua,t1[rs].min_fua);
}
void build_b(int l,int r,int p){
if(l==r){
if(b[l]>=0){
t2[p].max_zhengb=b[l];
t2[p].min_zhengb=b[l];
}
else{
t2[p].max_fub=b[l];
t2[p].min_fub=b[l];
}
return;
}
int mid=(l+r)>>1;
build_b(l,mid,ls);
build_b(mid+1,r,rs);
t2[p].max_zhengb=max(t2[ls].max_zhengb,t2[rs].max_zhengb);
t2[p].min_zhengb=min(t2[ls].min_zhengb,t2[rs].min_zhengb);
t2[p].max_fub=max(t2[ls].max_fub,t2[rs].max_fub);
t2[p].min_fub=min(t2[ls].min_fub,t2[rs].min_fub);
}
int query_max_a1(int l,int r,int L,int R,int p){
if(L<=l&&r<=R)return t1[p].max_zhenga;
int mid=(l+r)>>1;
int sum=-INF;
if(L<=mid)sum=query_max_a1(l,mid,L,R,ls);
if(R>mid)sum=max(query_max_a1(mid+1,r,L,R,ls),sum);
return sum;
}
int query_min_a1(int l,int r,int L,int R,int p){
if(L<=l&&r<=R)return t1[p].min_zhenga;
int mid=(l+r)>>1;
int sum=INF;
if(L<=mid)sum=query_min_a1(l,mid,L,R,ls);
if(R>mid)sum=min(query_min_a1(mid+1,r,L,R,ls),sum);
return sum;
}
int query_max_a2(int l,int r,int L,int R,int p){
if(L<=l&&r<=R)return t1[p].max_fua;
int mid=(l+r)>>1;
int sum=-INF;
if(L<=mid)sum=query_max_a2(l,mid,L,R,ls);
if(R>mid)sum=max(query_max_a2(mid+1,r,L,R,ls),sum);
return sum;
}
int query_min_a2(int l,int r,int L,int R,int p){
if(L<=l&&r<=R)return t1[p].min_fua;
int mid=(l+r)>>1;
int sum=INF;
if(L<=mid)sum=query_min_a2(l,mid,L,R,ls);
if(R>mid)sum=min(query_min_a2(mid+1,r,L,R,ls),sum);
return sum;
}
int query_max_b1(int l,int r,int L,int R,int p){
if(L<=l&&r<=R)return t2[p].max_zhengb;
int mid=(l+r)>>1;
int sum=-INF;
if(L<=mid)sum=query_max_b1(l,mid,L,R,ls);
if(R>mid)sum=max(query_max_b1(mid+1,r,L,R,ls),sum);
return sum;
}
int query_min_b1(int l,int r,int L,int R,int p){
if(L<=l&&r<=R)return t2[p].min_zhengb;
int mid=(l+r)>>1;
int sum=INF;
if(L<=mid)sum=query_min_b1(l,mid,L,R,ls);
if(R>mid)sum=min(query_min_b1(mid+1,r,L,R,ls),sum);
return sum;
}
int query_max_b2(int l,int r,int L,int R,int p){
if(L<=l&&r<=R)return t2[p].max_fub;
int mid=(l+r)>>1;
int sum=-INF;
if(L<=mid)sum=query_max_b2(l,mid,L,R,ls);
if(R>mid)sum=max(query_max_b2(mid+1,r,L,R,ls),sum);
return sum;
}
int query_min_b2(int l,int r,int L,int R,int p){
if(L<=l&&r<=R)return t2[p].min_fub;
int mid=(l+r)>>1;
int sum=INF;
if(L<=mid)sum=query_min_b2(l,mid,L,R,ls);
if(R>mid)sum=min(query_min_b2(mid+1,r,L,R,ls),sum);
return sum;
}
bool fa1,fa2,fb1,fb2;
int l1,l2,r1,r2;
ll ans;
int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
for(int i=1;i<=m;i++)
scanf("%d",b+i);
build_a(1,n,1);
build_b(1,m,1);
while(q--){
fa1=fa2=fb1=fb2=0;
scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
for(int i=l1;i<=r1;i++){
if(a[i]>=0)fa1=1;
else fa2=1;
}
for(int i=l2;i<=r2;i++){
if(a[i]>=0)fb1=1;
else fb2=1;
}
// printf("%d %d %d %d\n",query_max_a1(1,n,l1,r1,1),query_min_a1(1,n,l1,r1,1),query_max_a2(1,n,l1,r1,1),query_min_a2(1,n,l1,r1,1));
// printf("%d %d %d %d\n",query_max_b1(1,n,l2,r2,1),query_min_b1(1,n,l2,r2,1),query_max_b2(1,n,l2,r2,1),query_min_b2(1,n,l2,r2,1));
if(fb1&&fb2){
if(fa1&&!fa2)
ans=query_min_a1(1,n,l1,r1,1)*query_min_b2(1,n,l2,r2,1);
else if(!fa1&&fa2)
ans=query_max_a2(1,n,l1,r1,1)*query_max_b1(1,n,l2,r2,1);
else ans=max(query_min_a1(1,n,l1,r1,1)*query_min_b2(1,n,l2,r2,1),query_max_a2(1,n,l1,r1,1)*query_max_b1(1,n,l2,r2,1));
}
else if(fb1&&!fb2){
if(fa1) ans=query_max_a1(1,n,l1,r1,1)*query_max_b1(1,n,l2,r2,1);
else ans=query_max_a2(1,n,l1,r1,1)*query_max_b1(1,n,l2,r2,1);
}
else{
if(fa2) ans=query_min_a2(1,n,l1,r1,1)*query_max_b2(1,n,l2,r2,1);
else ans=query_min_a1(1,n,l1,r1,1)*query_max_b2(1,n,l2,r2,1);
}
printf("%lld\n",ans);
}
return 0;
}