有注释
代码量虽然有点大 但是还算比较容易明白的吧
(第一次参加NOIP,线段树还不会写,能把暴力打出来已经难上加难了)
评测记录这里 25pts,只过了特殊数据点
#include<bits/stdc++.h>
#define int long long
#define N 114514
using namespace std;
inline int read(){
int _=0,__=1;char ___=getchar();
while(___>'9'||___<'0'){if(___=='-') __=-1;___=getchar();}
while(___>='0'&&___<='9'){_=(_<<3)+(_<<1)+___-'0';___=getchar();}
return __==1?_:-_;
}
int n,m,q;
int a[N],b[N];
bool bt0a=1,bt0b=1,lt0a=1,lt0b=1;
//bt0=1 无负数 lt0=1 无正数
//bt0=0 有负数 lt0=0 有正数
signed main(){
cin>>n>>m>>q;
for(int i=1;i<=n;i++){
a[i]=read();
if(a[i]<0){bt0a=0;}
if(a[i]>0){lt0a=0;}
}
for(int i=1;i<=m;i++){
b[i]=read();
if(b[i]<0){bt0b=0;}
if(b[i]>0){lt0b=0;}
}
while(q--){
int l1,r1,l2,r2;
int maxa=0,mina=1e9,maxb=0,minb=1e9;
l1=read(); r1=read(); l2=read(); r2=read();
if(bt0a&&bt0b){//a b均无负数
for(int i=l1;i<=r1;i++){maxa=max(maxa,a[i]);}
for(int i=l2;i<=r2;i++){minb=min(minb,b[i]);}
cout<<maxa*minb<<endl;
//a取最大值 b取最小值
}else{
if(l1==r1){//操作区间长度为1
if(a[l1]==0){
cout<<0<<endl;
}else if(a[l1]>0){
for(int i=l2;i<=r2;i++){minb=min(minb,b[i]);}
cout<<a[l1]*minb<<endl;
}else if(a[l1]<0){
for(int i=l2;i<=r2;i++){maxb=max(maxb,b[i]);}
cout<<a[l1]*maxb<<endl;
}
//若a为0,则为0
//若a为正,b取最小值
//若a为负,b取最大值
}else if(l2==r2){
if(b[l2]==0){
cout<<0<<endl;
}else if(b[l2]>0){
for(int i=l1;i<=r1;i++){maxa=max(maxa,a[i]);}
cout<<b[l2]*maxa<<endl;
}else if(b[l2]<0){
for(int i=l1;i<=r1;i++){mina=min(mina,a[i]);}
cout<<b[l2]*mina<<endl;
}
//若b为0,则为0
//若b为正,a取最大值
//若b为负,a取最小值
}else{
if(bt0b){//b无负数
if(lt0a==0){//a有正数
for(int i=l1;i<=r1;i++){maxa=max(maxa,a[i]);} //a选择最大数
for(int i=l2;i<=r2;i++){minb=min(minb,b[i]);} //b选择最小数
cout<<maxa*minb<<endl;
}else{
for(int i=l1;i<=r1;i++){maxa=max(maxa,a[i]);} //a选择最小数
for(int i=l2;i<=r2;i++){maxb=max(maxb,b[i]);} //b选择最大数
cout<<maxa*maxb<<endl;
}
}else if(lt0b){//b无正数
if(bt0a==0){//a有负数
for(int i=l1;i<=r1;i++){mina=min(mina,a[i]);} //同上
for(int i=l2;i<=r2;i++){maxb=max(maxb,b[i]);}
cout<<mina*maxb<<endl;
}else{
for(int i=l1;i<=r1;i++){mina=min(mina,a[i]);}
for(int i=l2;i<=r2;i++){minb=max(minb,b[i]);}
cout<<mina*minb<<endl;
}
}else{
bool t=0;
for(int i=l1;i<=r1;i++){
if(a[i]==0){cout<<0<<endl; t=1; break;}
}
//如果a中有0,则输出0,做标记
if(t==0){
if(lt0a){//a无正数
for(int i=l1;i<=r1;i++){maxa=max(maxa,a[i]);}
for(int i=l2;i<=r2;i++){minb=max(minb,b[i]);}
cout<<maxa*minb<<endl;
}else if(bt0a){//a无负数
for(int i=l1;i<=r1;i++){mina=max(mina,a[i]);}
for(int i=l2;i<=r2;i++){maxb=max(maxb,b[i]);}
cout<<mina*maxb<<endl;
}else{
for(int i=l1;i<=r1;i++){
if(a[i]<0)maxa=max(maxa,a[i]);
else mina=min(mina,a[i]);
//此时a可能选择最大的负数,也可能选择最小的正数。由于a有优先决策的权力,所以他会会选择两种结果中更大的一个
//即答案为 max(a最大负数*b最大正数,a最小正数*b最小负数)。
}
for(int i=l2;i<=r2;i++){
minb=min(minb,b[i]);
maxb=max(maxb,a[i]);
}
cout<<max(maxa*maxb,mina*minb)<<endl;
}
}
}
}
}
}
return 0;
}