代码如下:
大概就是暴力分类的讨论用几个最值(正数最大最小、负数最大最小、0)这几个互相乘起来取最值。
我看了一下,貌似会算大,但又想不出来哪算错了。
求调
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T> inline void read(T& x);
template<typename... Args> inline void read(Args& ...args);
const int N=1e5+5;
const ll Inf=1ll*1e18+5;
int n,m,q;
ll a[N],b[N];
int lg[N];
struct st{
ll max_[N][20],min_[N][20];
ll _max[N][20],_min[N][20];
bool zero[N][20];
void init(ll* c,int len){
for(int i=1;i<=len;i++){
max_[i][0]=min_[i][0]=c[i];
_min[i][0]=(c[i]>0?c[i]:Inf);
_max[i][0]=(c[i]<0?c[i]:-Inf);
zero[i][0]=(c[i]==0);
}
for(int k=1;k<=lg[len];k++){
for(int l=1,r;(r=l+(1<<(k-1)))<=len;l++){
max_[l][k]=max(max_[l][k-1],max_[r][k-1]);
min_[l][k]=min(min_[l][k-1],min_[r][k-1]);
_min[l][k]=min(_min[l][k-1],_min[r][k-1]);
_max[l][k]=max(_max[l][k-1],_max[r][k-1]);
zero[l][k]|=zero[l][k-1]|zero[r][k-1];
}
}
}
ll ask_max(int l,int r){
int k=lg[r-l+1];
return max(max_[l][k],max_[r-(1<<k)+1][k]);
}
ll ask_min(int l,int r){
int k=lg[r-l+1];
return min(min_[l][k],min_[r-(1<<k)+1][k]);
}
ll get_max(int l,int r){
int k=lg[r-l+1];
return max(_max[l][k],_max[r-(1<<k)+1][k]);
}
ll get_min(int l,int r){
int k=lg[r-l+1];
return min(_min[l][k],_min[r-(1<<k)+1][k]);
}
bool get_0(int l,int r){
int k=lg[r-l+1];
return zero[l][k]|zero[r-(1<<k)+1][k];
}
};
st L,Q;
int main(){
read(n,m,q);
for(int i=2;i<=max(n,m);i++) lg[i]=lg[i>>1]+1;
bool flag=1;
for(int i=1;i<=n;i++) read(a[i]),flag&=(a[i]>0);
for(int i=1;i<=m;i++) read(b[i]),flag&=(b[i]>0);
L.init(a,n),Q.init(b,m);
for(int l1,r1,l2,r2;q--;){
read(l1,r1,l2,r2);
ll ans=-Inf;
if(flag){
printf("%lld\n",L.ask_max(l1,r1)*Q.ask_min(l2,r2));
continue;
}
if(l1==r1){
if(a[l1]>0) ans=a[l1]*Q.ask_min(l2,r2);
else ans=a[l1]*Q.ask_max(l2,r2);
printf("%lld\n",ans);
continue;
}
if(l2==r2){
if(b[l2]>0) ans=b[l2]*L.ask_max(l1,r1);
else ans=b[l2]*L.ask_min(l1,r1);
printf("%lld\n",ans);
continue;
}//这上面的是判特殊情况
if(rand()&1){//这个是迷惑行为,选择暴力
for(int i=l1;i<=r1;i++){
ll now=Inf;
if(Q.get_max(l2,r2)!=-Inf) now=min(now,a[i]*Q.get_max(l2,r2));
if(Q.get_min(l2,r2)!=Inf) now=min(now,a[i]*Q.get_min(l2,r2));
now=min(now,a[i]*Q.ask_max(l2,r2));
now=min(now,a[i]*Q.ask_min(l2,r2));
if(now>ans) ans=now;
}
printf("%lld\n",ans);
continue;
}
else{
ll L_Up=L.ask_max(l1,r1),L_Down=L.ask_min(l1,r1);
ll L_up=L.get_max(l1,r1),L_down=L.get_min(l1,r1);
ll Q_Up=Q.ask_max(l2,r2),Q_Down=Q.ask_max(l2,r2);
ll Q_up=Q.get_max(l2,r2),Q_down=Q.get_min(l2,r2);
bool L_0=L.get_0(l1,r1),Q_0=Q.get_0(l2,r2);
ll now=min(L_Up*Q_Up,L_Up*Q_Down);
if(Q_up!=-Inf) now=min(now,L_Up*Q_up);
if(Q_down!=Inf) now=min(now,L_Up*Q_down);
if(Q_0) now=min(now,0ll);
ans=max(ans,now);
if(L_up!=-Inf){
now=min(L_up*Q_Up,L_up*Q_Down);
if(Q_up!=-Inf) now=min(now,L_up*Q_up);
if(Q_down!=Inf) now=min(now,L_up*Q_down);
if(Q_0) now=min(now,0ll);
ans=max(ans,now);
}
now=min(L_Down*Q_Up,L_Down*Q_Down);
if(Q_up!=-Inf) now=min(now,L_Down*Q_up);
if(Q_down!=Inf) now=min(now,L_Down*Q_down);
if(Q_0) now=min(now,0ll);
ans=max(ans,now);
if(L_down!=Inf){
now=min(L_down*Q_Up,L_down*Q_Down);
if(Q_up!=-Inf) now=min(now,L_down*Q_up);
if(Q_down!=Inf) now=min(now,L_down*Q_down);
if(Q_0) now=min(now,0ll);
ans=max(ans,now);
}
if(L_0) ans=max(ans,0ll);
printf("%lld\n",ans);
continue;
}
}
return 0;
}
template<typename T> inline void read(T& x){
x=0;bool flag=0;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') flag=1;
if(flag) for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)-(ch&15);
else for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch&15);
}
template<typename... Args> inline void read(Args& ...args){
int arg[]{(read(args),0)...};
if(0) *arg=*arg;
}